From d2bb7aaf84819903ec51f2e68c43b81814c38dd0 Mon Sep 17 00:00:00 2001 From: Dong Nguyen Date: Thu, 28 Jul 2022 16:33:13 +0700 Subject: [PATCH 1/3] v6.0.0rc3 - Stop using event driven pattern, keep API simple as before - Reorganize package structure & refactor main workflow - Start support JSON Feed - Improve test coverage --- README.md | 109 +- build.test.js | 6 +- dist/cjs/feed-reader.js | 1211 +++++++++-------- dist/cjs/package.json | 2 +- eval.js | 24 +- package.json | 9 +- src/config.js | 16 +- src/config.test.js | 50 +- src/main.js | 97 +- src/main.test.js | 258 ++-- src/utils/isValidUrl.js | 10 - src/utils/{purifyUrl.js => linker.js} | 22 +- src/utils/linker.test.js | 138 ++ src/utils/logger.js | 15 - src/utils/normalizer.js | 22 + src/utils/normalizer.test.js | 13 + src/utils/parseAtomFeed.js | 101 ++ src/utils/parseJsonFeed.js | 66 + src/utils/parseRssFeed.js | 68 + src/utils/parser.js | 131 -- src/utils/purifyUrl.test.js | 54 - src/utils/retrieve.js | 13 +- src/utils/retrieve.test.js | 52 +- src/utils/validator.js | 17 - src/utils/validator.test.js | 34 - src/utils/xml2obj.js | 15 - src/utils/xmlparser.js | 26 + src/utils/xmlparser.test.js | 41 + test-data/atom-feed-standard-realworld.xml | 283 ++++ test-data/atom-feed-standard.xml | 30 + .../{another-atom.xml => atom-multilinks.xml} | 4 +- test-data/atom-with-single-item.xml | 24 - test-data/atom.xml | 31 - test-data/json-feed-standard-realworld.json | 233 ++++ test-data/json-feed-standard.json | 23 + test-data/rss-feed-standard-realworld.xml | 318 +++++ test-data/rss-feed-standard.xml | 19 + test-data/rss-with-single-item.xml | 22 - test-data/rss.xml | 30 - 39 files changed, 2305 insertions(+), 1332 deletions(-) mode change 100755 => 100644 src/main.test.js delete mode 100755 src/utils/isValidUrl.js rename src/utils/{purifyUrl.js => linker.js} (72%) create mode 100755 src/utils/linker.test.js delete mode 100755 src/utils/logger.js create mode 100644 src/utils/normalizer.js create mode 100644 src/utils/normalizer.test.js create mode 100644 src/utils/parseAtomFeed.js create mode 100644 src/utils/parseJsonFeed.js create mode 100644 src/utils/parseRssFeed.js delete mode 100755 src/utils/parser.js delete mode 100755 src/utils/purifyUrl.test.js delete mode 100755 src/utils/validator.js delete mode 100755 src/utils/validator.test.js delete mode 100755 src/utils/xml2obj.js create mode 100755 src/utils/xmlparser.js create mode 100755 src/utils/xmlparser.test.js create mode 100644 test-data/atom-feed-standard-realworld.xml create mode 100644 test-data/atom-feed-standard.xml rename test-data/{another-atom.xml => atom-multilinks.xml} (84%) mode change 100755 => 100644 delete mode 100644 test-data/atom-with-single-item.xml delete mode 100755 test-data/atom.xml create mode 100644 test-data/json-feed-standard-realworld.json create mode 100644 test-data/json-feed-standard.json create mode 100644 test-data/rss-feed-standard-realworld.xml create mode 100644 test-data/rss-feed-standard.xml delete mode 100644 test-data/rss-with-single-item.xml delete mode 100755 test-data/rss.xml diff --git a/README.md b/README.md index d9ee068..dd7fb94 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # feed-reader -Load and parse RSS/ATOM data from given feed url. +Load and parse ATOM/RSS/JSON data from given feed url. [![NPM](https://badge.fury.io/js/feed-reader.svg)](https://badge.fury.io/js/feed-reader) ![CI test](https://github.com/ndaidong/feed-reader/workflows/ci-test/badge.svg) @@ -33,13 +33,11 @@ read(url).then((feed) => { ## APIs - [.read(String url)](#readstring-url) -- [The events](#the-events) - - [.resetEvents()](#reset-event-listeners) - [Configuration methods](#configuration-methods) ### read(String url) -Load and extract feed data from given RSS/ATOM source. Return a Promise object. +Load and extract feed data from given RSS/ATOM/JSON source. Return a Promise object. Example: @@ -62,6 +60,7 @@ const getFeedData = async (url) => { getFeedData('https://news.google.com/rss') getFeedData('https://news.google.com/atom') +getFeedData('https://adactio.com/journal/feed.json') ``` Feed data object retuned by `read()` method should look like below: @@ -86,96 +85,6 @@ Feed data object retuned by `read()` method should look like below: } ``` -### The events - -Since v6.0.0, `feed-reader` supports event-driven pattern for easier writing code with more control. - -- `onSuccess(Function callback)` -- `onError(Function callback)` -- `onComplete(Function callback)` - -The following example will explain better than any word: - -```js -import { read, onSuccess, onError, onComplete } from 'feed-reader' - -onSuccess((url, feed) => { - console.log(`Feed data from ${url} has been parsed successfully`) - console.log('`feed` is always an object that contains feed data') - console.log(feed) -}) - -onError((url, err) => { - console.log(`Error occurred while processing ${url}`) - console.log('There is a message and reason:') - console.log(err) -}) - -onComplete((url, result, error) => { - console.log(`Finish processing ${url}`) - console.log('`result` may be feed data or null') - console.log(result) - console.log('`error` may be an error object or null') - if (error) { - console.log(error.message) - console.log(error.reason) - } -}) - -read('https://news.google.com/rss') -read('https://google.com') -``` - -We can mix both style together, for example to handle the error: - -```js -import { read, onError } from 'feed-reader' - -onError((url, err) => { - console.log(`Error occurred while processing ${url}`) - console.log('There is a message and reason:') - console.log(err) -}) - -const getFeedData = async (url) => { - const result = await read(url) - // `result` may be feed data or null - return result -} - -getFeedData('https://news.google.com/rss') -```` - -In almost cases, using just `onComplete` is enough: - -```js -import { read, onComplete } from 'feed-reader' - -onComplete((url, result, error) => { - console.log(`Finish processing ${url}`) - if (result) { - // save feed data - console.log(result) - } - if (error) { - // handle error info - console.log(error) - } -}) - -read('https://news.google.com/rss') -```` - -#### Reset event listeners - -Use method `resetEvents()` when you want to clear registered listeners from all events. - -```js -import { resetEvents } from 'feed-reader' - -resetEvents() -```` - ### Configuration methods #### `setRequestOptions(Object requestOptions)` @@ -188,6 +97,18 @@ Return current request options. Default values can be found [here](https://github.com/ndaidong/feed-reader/blob/main/src/config.js#L5). +#### `setReaderOptions(Object readerOptions)` + +To change default reader options. + +- `descriptionMaxLen`: Number, max num of chars for description (default: `210`) +- `includeFullContent`: Boolean, add `content` to entry if available (default: `false`) +- `convertPubDateToISO`: Boolean, reformat published date to [ISO standard](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) (default: `true`) + +#### `getReaderOptions()` + +Return current reader options. + ## Test diff --git a/build.test.js b/build.test.js index 0880c6a..7721fe6 100644 --- a/build.test.js +++ b/build.test.js @@ -13,16 +13,16 @@ const cjsFile = `./dist/cjs/${pkg.name}.js` const cjsPkg = JSON.parse(readFileSync('./dist/cjs/package.json')) describe('Validate commonjs version output', () => { - test(`Check if ${cjsFile} created`, () => { + test(`check if ${cjsFile} created`, () => { expect(existsSync(cjsFile)).toBeTruthy() }) - test('Check if cjs package info updated', () => { + test('check if cjs package info updated', () => { expect(cjsPkg.name).toEqual(`${pkg.name}-cjs`) expect(cjsPkg.version).toEqual(pkg.version) }) const constent = readFileSync(cjsFile, 'utf8') const lines = constent.split('\n') - test('Check if file meta contains package info', () => { + test('check if file meta contains package info', () => { expect(lines[0].includes(`${pkg.name}@${pkg.version}`)).toBeTruthy() expect(lines[0].includes(pkg.author)).toBeTruthy() expect(lines[0].includes(pkg.license)).toBeTruthy() diff --git a/dist/cjs/feed-reader.js b/dist/cjs/feed-reader.js index 90ea6df..354f02d 100644 --- a/dist/cjs/feed-reader.js +++ b/dist/cjs/feed-reader.js @@ -1,4 +1,4 @@ -// feed-reader@6.0.0rc2, by @ndaidong - built with esbuild at 2022-07-16T03:09:04.163Z - published under MIT license +// feed-reader@6.0.0rc3, by @ndaidong - built with esbuild at 2022-07-28T09:33:03.350Z - published under MIT license var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; @@ -9,8 +9,8 @@ var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { - for (var name2 in all) - __defProp(target, name2, { get: all[name2], enumerable: true }); + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { @@ -23,9 +23,9 @@ var __copyProps = (to, from, except, desc) => { var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/bind.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/bind.js var require_bind = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/bind.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/bind.js"(exports, module2) { "use strict"; module2.exports = function bind(fn, thisArg) { return function wrap() { @@ -39,9 +39,9 @@ var require_bind = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/utils.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/utils.js var require_utils = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/utils.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/utils.js"(exports, module2) { "use strict"; var bind = require_bind(); var toString = Object.prototype.toString; @@ -57,7 +57,7 @@ var require_utils = __commonJS({ return kindOf(thing) === type; }; } - function isArray3(val) { + function isArray5(val) { return Array.isArray(val); } function isUndefined2(val) { @@ -76,13 +76,13 @@ var require_utils = __commonJS({ } return result; } - function isString3(val) { + function isString4(val) { return typeof val === "string"; } function isNumber2(val) { return typeof val === "number"; } - function isObject3(val) { + function isObject4(val) { return val !== null && typeof val === "object"; } function isPlainObject(val) { @@ -100,7 +100,7 @@ var require_utils = __commonJS({ return toString.call(val) === "[object Function]"; } function isStream(val) { - return isObject3(val) && isFunction2(val.pipe); + return isObject4(val) && isFunction2(val.pipe); } function isFormData(thing) { var pattern = "[object FormData]"; @@ -123,7 +123,7 @@ var require_utils = __commonJS({ if (typeof obj !== "object") { obj = [obj]; } - if (isArray3(obj)) { + if (isArray5(obj)) { for (var i = 0, l = obj.length; i < l; i++) { fn.call(null, obj[i], i, obj); } @@ -142,7 +142,7 @@ var require_utils = __commonJS({ result[key] = merge(result[key], val); } else if (isPlainObject(val)) { result[key] = merge({}, val); - } else if (isArray3(val)) { + } else if (isArray5(val)) { result[key] = val.slice(); } else { result[key] = val; @@ -221,14 +221,14 @@ var require_utils = __commonJS({ }; }(typeof Uint8Array !== "undefined" && Object.getPrototypeOf(Uint8Array)); module2.exports = { - isArray: isArray3, + isArray: isArray5, isArrayBuffer, isBuffer, isFormData, isArrayBufferView, - isString: isString3, + isString: isString4, isNumber: isNumber2, - isObject: isObject3, + isObject: isObject4, isPlainObject, isUndefined: isUndefined2, isDate: isDate2, @@ -255,9 +255,9 @@ var require_utils = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/buildURL.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/buildURL.js var require_buildURL = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/buildURL.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/buildURL.js"(exports, module2) { "use strict"; var utils = require_utils(); function encode(val) { @@ -306,9 +306,9 @@ var require_buildURL = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/InterceptorManager.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/InterceptorManager.js var require_InterceptorManager = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/InterceptorManager.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/InterceptorManager.js"(exports, module2) { "use strict"; var utils = require_utils(); function InterceptorManager() { @@ -339,25 +339,25 @@ var require_InterceptorManager = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/normalizeHeaderName.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/normalizeHeaderName.js var require_normalizeHeaderName = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/normalizeHeaderName.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/normalizeHeaderName.js"(exports, module2) { "use strict"; var utils = require_utils(); module2.exports = function normalizeHeaderName(headers, normalizedName) { - utils.forEach(headers, function processHeader(value, name2) { - if (name2 !== normalizedName && name2.toUpperCase() === normalizedName.toUpperCase()) { + utils.forEach(headers, function processHeader(value, name) { + if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { headers[normalizedName] = value; - delete headers[name2]; + delete headers[name]; } }); }; } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/AxiosError.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/AxiosError.js var require_AxiosError = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/AxiosError.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/AxiosError.js"(exports, module2) { "use strict"; var utils = require_utils(); function AxiosError(message, code, config, request, response) { @@ -404,13 +404,13 @@ var require_AxiosError = __commonJS({ }); Object.defineProperties(AxiosError, descriptors); Object.defineProperty(prototype, "isAxiosError", { value: true }); - AxiosError.from = function(error2, code, config, request, response, customProps) { + AxiosError.from = function(error, code, config, request, response, customProps) { var axiosError = Object.create(prototype); - utils.toFlatObject(error2, axiosError, function filter(obj) { + utils.toFlatObject(error, axiosError, function filter(obj) { return obj !== Error.prototype; }); - AxiosError.call(axiosError, error2.message, code, config, request, response); - axiosError.name = error2.name; + AxiosError.call(axiosError, error.message, code, config, request, response); + axiosError.name = error.name; customProps && Object.assign(axiosError, customProps); return axiosError; }; @@ -418,9 +418,9 @@ var require_AxiosError = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/defaults/transitional.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/defaults/transitional.js var require_transitional = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/defaults/transitional.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/defaults/transitional.js"(exports, module2) { "use strict"; module2.exports = { silentJSONParsing: true, @@ -430,9 +430,9 @@ var require_transitional = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/toFormData.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/toFormData.js var require_toFormData = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/toFormData.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/toFormData.js"(exports, module2) { "use strict"; var utils = require_utils(); function toFormData(obj, formData) { @@ -484,9 +484,9 @@ var require_toFormData = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/settle.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/settle.js var require_settle = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/settle.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/settle.js"(exports, module2) { "use strict"; var AxiosError = require_AxiosError(); module2.exports = function settle(resolve, reject, response) { @@ -500,16 +500,16 @@ var require_settle = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/cookies.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/cookies.js var require_cookies = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/cookies.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/cookies.js"(exports, module2) { "use strict"; var utils = require_utils(); module2.exports = utils.isStandardBrowserEnv() ? function standardBrowserEnv() { return { - write: function write(name2, value, expires, path, domain, secure) { + write: function write(name, value, expires, path, domain, secure) { var cookie = []; - cookie.push(name2 + "=" + encodeURIComponent(value)); + cookie.push(name + "=" + encodeURIComponent(value)); if (utils.isNumber(expires)) { cookie.push("expires=" + new Date(expires).toGMTString()); } @@ -524,12 +524,12 @@ var require_cookies = __commonJS({ } document.cookie = cookie.join("; "); }, - read: function read2(name2) { - var match = document.cookie.match(new RegExp("(^|;\\s*)(" + name2 + ")=([^;]*)")); + read: function read2(name) { + var match = document.cookie.match(new RegExp("(^|;\\s*)(" + name + ")=([^;]*)")); return match ? decodeURIComponent(match[3]) : null; }, - remove: function remove(name2) { - this.write(name2, "", Date.now() - 864e5); + remove: function remove(name) { + this.write(name, "", Date.now() - 864e5); } }; }() : function nonStandardBrowserEnv() { @@ -546,9 +546,9 @@ var require_cookies = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/isAbsoluteURL.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/isAbsoluteURL.js var require_isAbsoluteURL = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/isAbsoluteURL.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/isAbsoluteURL.js"(exports, module2) { "use strict"; module2.exports = function isAbsoluteURL(url) { return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); @@ -556,9 +556,9 @@ var require_isAbsoluteURL = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/combineURLs.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/combineURLs.js var require_combineURLs = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/combineURLs.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/combineURLs.js"(exports, module2) { "use strict"; module2.exports = function combineURLs(baseURL, relativeURL) { return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL; @@ -566,9 +566,9 @@ var require_combineURLs = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/buildFullPath.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/buildFullPath.js var require_buildFullPath = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/buildFullPath.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/buildFullPath.js"(exports, module2) { "use strict"; var isAbsoluteURL = require_isAbsoluteURL(); var combineURLs = require_combineURLs(); @@ -581,9 +581,9 @@ var require_buildFullPath = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/parseHeaders.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/parseHeaders.js var require_parseHeaders = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/parseHeaders.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/parseHeaders.js"(exports, module2) { "use strict"; var utils = require_utils(); var ignoreDuplicateOf = [ @@ -633,9 +633,9 @@ var require_parseHeaders = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/isURLSameOrigin.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/isURLSameOrigin.js var require_isURLSameOrigin = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/isURLSameOrigin.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/isURLSameOrigin.js"(exports, module2) { "use strict"; var utils = require_utils(); module2.exports = utils.isStandardBrowserEnv() ? function standardBrowserEnv() { @@ -673,9 +673,9 @@ var require_isURLSameOrigin = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/cancel/CanceledError.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/cancel/CanceledError.js var require_CanceledError = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/cancel/CanceledError.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/cancel/CanceledError.js"(exports, module2) { "use strict"; var AxiosError = require_AxiosError(); var utils = require_utils(); @@ -690,9 +690,9 @@ var require_CanceledError = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/parseProtocol.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/parseProtocol.js var require_parseProtocol = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/parseProtocol.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/parseProtocol.js"(exports, module2) { "use strict"; module2.exports = function parseProtocol(url) { var match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); @@ -701,9 +701,9 @@ var require_parseProtocol = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/adapters/xhr.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/adapters/xhr.js var require_xhr = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/adapters/xhr.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/adapters/xhr.js"(exports, module2) { "use strict"; var utils = require_utils(); var settle = require_settle(); @@ -866,13 +866,13 @@ var require_ms = __commonJS({ options = options || {}; var type = typeof val; if (type === "string" && val.length > 0) { - return parse2(val); + return parse(val); } else if (type === "number" && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(val)); }; - function parse2(str) { + function parse(str) { str = String(str); if (str.length > 100) { return; @@ -958,9 +958,9 @@ var require_ms = __commonJS({ } return ms + " ms"; } - function plural(ms, msAbs, n, name2) { + function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; - return Math.round(ms / n) + " " + name2 + (isPlural ? "s" : ""); + return Math.round(ms / n) + " " + name + (isPlural ? "s" : ""); } } }); @@ -997,11 +997,11 @@ var require_common = __commonJS({ let enableOverride = null; let namespacesCache; let enabledCache; - function debug2(...args) { - if (!debug2.enabled) { + function debug(...args) { + if (!debug.enabled) { return; } - const self = debug2; + const self = debug; const curr = Number(new Date()); const ms = curr - (prevTime || curr); self.diff = ms; @@ -1031,12 +1031,12 @@ var require_common = __commonJS({ const logFn = self.log || createDebug.log; logFn.apply(self, args); } - debug2.namespace = namespace; - debug2.useColors = createDebug.useColors(); - debug2.color = createDebug.selectColor(namespace); - debug2.extend = extend; - debug2.destroy = createDebug.destroy; - Object.defineProperty(debug2, "enabled", { + debug.namespace = namespace; + debug.useColors = createDebug.useColors(); + debug.color = createDebug.selectColor(namespace); + debug.extend = extend; + debug.destroy = createDebug.destroy; + Object.defineProperty(debug, "enabled", { enumerable: true, configurable: false, get: () => { @@ -1054,9 +1054,9 @@ var require_common = __commonJS({ } }); if (typeof createDebug.init === "function") { - createDebug.init(debug2); + createDebug.init(debug); } - return debug2; + return debug; } function extend(namespace, delimiter) { const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace); @@ -1091,19 +1091,19 @@ var require_common = __commonJS({ createDebug.enable(""); return namespaces; } - function enabled(name2) { - if (name2[name2.length - 1] === "*") { + function enabled(name) { + if (name[name.length - 1] === "*") { return true; } let i; let len; for (i = 0, len = createDebug.skips.length; i < len; i++) { - if (createDebug.skips[i].test(name2)) { + if (createDebug.skips[i].test(name)) { return false; } } for (i = 0, len = createDebug.names.length; i < len; i++) { - if (createDebug.names[i].test(name2)) { + if (createDebug.names[i].test(name)) { return true; } } @@ -1261,14 +1261,14 @@ var require_browser = __commonJS({ } else { exports.storage.removeItem("debug"); } - } catch (error2) { + } catch (error) { } } function load() { let r; try { r = exports.storage.getItem("debug"); - } catch (error2) { + } catch (error) { } if (!r && typeof process !== "undefined" && "env" in process) { r = process.env.DEBUG; @@ -1278,7 +1278,7 @@ var require_browser = __commonJS({ function localstorage() { try { return localStorage; - } catch (error2) { + } catch (error) { } } module2.exports = require_common()(exports); @@ -1286,8 +1286,8 @@ var require_browser = __commonJS({ formatters.j = function(v) { try { return JSON.stringify(v); - } catch (error2) { - return "[UnexpectedJSONParseError]: " + error2.message; + } catch (error) { + return "[UnexpectedJSONParseError]: " + error.message; } }; } @@ -1504,7 +1504,7 @@ var require_node = __commonJS({ 221 ]; } - } catch (error2) { + } catch (error) { } exports.inspectOpts = Object.keys(process.env).filter((key) => { return /^debug_/i.test(key); @@ -1529,15 +1529,15 @@ var require_node = __commonJS({ return "colors" in exports.inspectOpts ? Boolean(exports.inspectOpts.colors) : tty.isatty(process.stderr.fd); } function formatArgs(args) { - const { namespace: name2, useColors: useColors2 } = this; + const { namespace: name, useColors: useColors2 } = this; if (useColors2) { const c = this.color; const colorCode = "\x1B[3" + (c < 8 ? c : "8;5;" + c); - const prefix = ` ${colorCode};1m${name2} \x1B[0m`; + const prefix = ` ${colorCode};1m${name} \x1B[0m`; args[0] = prefix + args[0].split("\n").join("\n" + prefix); args.push(colorCode + "m+" + module2.exports.humanize(this.diff) + "\x1B[0m"); } else { - args[0] = getDate() + name2 + " " + args[0]; + args[0] = getDate() + name + " " + args[0]; } } function getDate() { @@ -1559,11 +1559,11 @@ var require_node = __commonJS({ function load() { return process.env.DEBUG; } - function init(debug2) { - debug2.inspectOpts = {}; + function init(debug) { + debug.inspectOpts = {}; const keys = Object.keys(exports.inspectOpts); for (let i = 0; i < keys.length; i++) { - debug2.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; } } module2.exports = require_common()(exports); @@ -1590,36 +1590,36 @@ var require_src = __commonJS({ } }); -// node_modules/.pnpm/follow-redirects@1.15.1_debug@4.3.4/node_modules/follow-redirects/debug.js +// node_modules/.pnpm/follow-redirects@1.15.1/node_modules/follow-redirects/debug.js var require_debug = __commonJS({ - "node_modules/.pnpm/follow-redirects@1.15.1_debug@4.3.4/node_modules/follow-redirects/debug.js"(exports, module2) { - var debug2; + "node_modules/.pnpm/follow-redirects@1.15.1/node_modules/follow-redirects/debug.js"(exports, module2) { + var debug; module2.exports = function() { - if (!debug2) { + if (!debug) { try { - debug2 = require_src()("follow-redirects"); - } catch (error2) { + debug = require_src()("follow-redirects"); + } catch (error) { } - if (typeof debug2 !== "function") { - debug2 = function() { + if (typeof debug !== "function") { + debug = function() { }; } } - debug2.apply(null, arguments); + debug.apply(null, arguments); }; } }); -// node_modules/.pnpm/follow-redirects@1.15.1_debug@4.3.4/node_modules/follow-redirects/index.js +// node_modules/.pnpm/follow-redirects@1.15.1/node_modules/follow-redirects/index.js var require_follow_redirects = __commonJS({ - "node_modules/.pnpm/follow-redirects@1.15.1_debug@4.3.4/node_modules/follow-redirects/index.js"(exports, module2) { + "node_modules/.pnpm/follow-redirects@1.15.1/node_modules/follow-redirects/index.js"(exports, module2) { var url = require("url"); var URL2 = url.URL; var http = require("http"); var https = require("https"); var Writable = require("stream").Writable; var assert = require("assert"); - var debug2 = require_debug(); + var debug = require_debug(); var events = ["abort", "aborted", "connect", "error", "socket", "timeout"]; var eventHandlers = /* @__PURE__ */ Object.create(null); events.forEach(function(event) { @@ -1702,13 +1702,13 @@ var require_follow_redirects = __commonJS({ this._ending = true; } }; - RedirectableRequest.prototype.setHeader = function(name2, value) { - this._options.headers[name2] = value; - this._currentRequest.setHeader(name2, value); + RedirectableRequest.prototype.setHeader = function(name, value) { + this._options.headers[name] = value; + this._currentRequest.setHeader(name, value); }; - RedirectableRequest.prototype.removeHeader = function(name2) { - delete this._options.headers[name2]; - this._currentRequest.removeHeader(name2); + RedirectableRequest.prototype.removeHeader = function(name) { + delete this._options.headers[name]; + this._currentRequest.removeHeader(name); }; RedirectableRequest.prototype.setTimeout = function(msecs, callback) { var self = this; @@ -1814,10 +1814,10 @@ var require_follow_redirects = __commonJS({ var i = 0; var self = this; var buffers = this._requestBodyBuffers; - (function writeNext(error2) { + (function writeNext(error) { if (request === self._currentRequest) { - if (error2) { - self.emit("error", error2); + if (error) { + self.emit("error", error); } else if (i < buffers.length) { var buffer = buffers[i++]; if (!request.finished) { @@ -1877,7 +1877,7 @@ var require_follow_redirects = __commonJS({ this.emit("error", new RedirectionError(cause)); return; } - debug2("redirecting to", redirectUrl); + debug("redirecting to", redirectUrl); this._isRedirect = true; var redirectUrlParts = url.parse(redirectUrl); Object.assign(this._options, redirectUrlParts); @@ -1943,7 +1943,7 @@ var require_follow_redirects = __commonJS({ }, input, options); options.nativeProtocols = nativeProtocols; assert.equal(options.protocol, protocol, "protocol mismatch"); - debug2("options", options); + debug("options", options); return new RedirectableRequest(options, callback); } function get(input, options, callback) { @@ -2017,18 +2017,18 @@ var require_follow_redirects = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/env/data.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/env/data.js var require_data = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/env/data.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/env/data.js"(exports, module2) { module2.exports = { "version": "0.27.2" }; } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/adapters/http.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/adapters/http.js var require_http = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/adapters/http.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/adapters/http.js"(exports, module2) { "use strict"; var utils = require_utils(); var settle = require_settle(); @@ -2084,8 +2084,8 @@ var require_http = __commonJS({ var data = config.data; var headers = config.headers; var headerNames = {}; - Object.keys(headers).forEach(function storeLowerName(name2) { - headerNames[name2.toLowerCase()] = name2; + Object.keys(headers).forEach(function storeLowerName(name) { + headerNames[name.toLowerCase()] = name; }); if ("user-agent" in headerNames) { if (!headers[headerNames["user-agent"]]) { @@ -11279,17 +11279,17 @@ var require_iterate = __commonJS({ module2.exports = iterate; function iterate(list, iterator, state, callback) { var key = state["keyedList"] ? state["keyedList"][state.index] : state.index; - state.jobs[key] = runJob(iterator, key, list[key], function(error2, output) { + state.jobs[key] = runJob(iterator, key, list[key], function(error, output) { if (!(key in state.jobs)) { return; } delete state.jobs[key]; - if (error2) { + if (error) { abort(state); } else { state.results[key] = output; } - callback(error2, state.results); + callback(error, state.results); }); } function runJob(iterator, key, item, callback) { @@ -11353,9 +11353,9 @@ var require_parallel = __commonJS({ function parallel(list, iterator, callback) { var state = initState(list); while (state.index < (state["keyedList"] || list).length) { - iterate(list, iterator, state, function(error2, result) { - if (error2) { - callback(error2, result); + iterate(list, iterator, state, function(error, result) { + if (error) { + callback(error, result); return; } if (Object.keys(state.jobs).length === 0) { @@ -11381,9 +11381,9 @@ var require_serialOrdered = __commonJS({ module2.exports.descending = descending; function serialOrdered(list, iterator, sortMethod, callback) { var state = initState(list, sortMethod); - iterate(list, iterator, state, function iteratorHandler(error2, result) { - if (error2) { - callback(error2, result); + iterate(list, iterator, state, function iteratorHandler(error, result) { + if (error) { + callback(error, result); return; } state.index++; @@ -11726,10 +11726,10 @@ var require_form_data = __commonJS({ this.pipe(request); if (cb) { var onResponse; - var callback = function(error2, responce) { + var callback = function(error, responce) { request.removeListener("error", callback); request.removeListener("response", onResponse); - return cb.call(this, error2, responce); + return cb.call(this, error, responce); }; onResponse = callback.bind(this, null); request.on("error", callback); @@ -11751,16 +11751,16 @@ var require_form_data = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/defaults/env/FormData.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/defaults/env/FormData.js var require_FormData = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/defaults/env/FormData.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/defaults/env/FormData.js"(exports, module2) { module2.exports = require_form_data(); } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/defaults/index.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/defaults/index.js var require_defaults = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/defaults/index.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/defaults/index.js"(exports, module2) { "use strict"; var utils = require_utils(); var normalizeHeaderName = require_normalizeHeaderName(); @@ -11871,15 +11871,15 @@ var require_defaults = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/transformData.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/transformData.js var require_transformData = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/transformData.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/transformData.js"(exports, module2) { "use strict"; var utils = require_utils(); var defaults = require_defaults(); module2.exports = function transformData(data, headers, fns) { var context = this || defaults; - utils.forEach(fns, function transform(fn) { + utils.forEach(fns, function transform4(fn) { data = fn.call(context, data, headers); }); return data; @@ -11887,9 +11887,9 @@ var require_transformData = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/cancel/isCancel.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/cancel/isCancel.js var require_isCancel = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/cancel/isCancel.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/cancel/isCancel.js"(exports, module2) { "use strict"; module2.exports = function isCancel(value) { return !!(value && value.__CANCEL__); @@ -11897,9 +11897,9 @@ var require_isCancel = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/dispatchRequest.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/dispatchRequest.js var require_dispatchRequest = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/dispatchRequest.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/dispatchRequest.js"(exports, module2) { "use strict"; var utils = require_utils(); var transformData = require_transformData(); @@ -11940,9 +11940,9 @@ var require_dispatchRequest = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/mergeConfig.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/mergeConfig.js var require_mergeConfig = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/mergeConfig.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/mergeConfig.js"(exports, module2) { "use strict"; var utils = require_utils(); module2.exports = function mergeConfig(config1, config2) { @@ -12023,9 +12023,9 @@ var require_mergeConfig = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/validator.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/validator.js var require_validator = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/validator.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/validator.js"(exports, module2) { "use strict"; var VERSION = require_data().version; var AxiosError = require_AxiosError(); @@ -12080,9 +12080,9 @@ var require_validator = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/Axios.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/Axios.js var require_Axios = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/core/Axios.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/Axios.js"(exports, module2) { "use strict"; var utils = require_utils(); var buildURL = require_buildURL(); @@ -12152,15 +12152,15 @@ var require_Axios = __commonJS({ var onRejected = requestInterceptorChain.shift(); try { newConfig = onFulfilled(newConfig); - } catch (error2) { - onRejected(error2); + } catch (error) { + onRejected(error); break; } } try { promise = dispatchRequest(newConfig); - } catch (error2) { - return Promise.reject(error2); + } catch (error) { + return Promise.reject(error); } while (responseInterceptorChain.length) { promise = promise.then(responseInterceptorChain.shift(), responseInterceptorChain.shift()); @@ -12201,9 +12201,9 @@ var require_Axios = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/cancel/CancelToken.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/cancel/CancelToken.js var require_CancelToken = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/cancel/CancelToken.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/cancel/CancelToken.js"(exports, module2) { "use strict"; var CanceledError = require_CanceledError(); function CancelToken(executor) { @@ -12283,9 +12283,9 @@ var require_CancelToken = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/spread.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/spread.js var require_spread = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/spread.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/spread.js"(exports, module2) { "use strict"; module2.exports = function spread(callback) { return function wrap(arr) { @@ -12295,9 +12295,9 @@ var require_spread = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/isAxiosError.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/isAxiosError.js var require_isAxiosError = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/helpers/isAxiosError.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/isAxiosError.js"(exports, module2) { "use strict"; var utils = require_utils(); module2.exports = function isAxiosError(payload) { @@ -12306,9 +12306,9 @@ var require_isAxiosError = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/axios.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/axios.js var require_axios = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/lib/axios.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/axios.js"(exports, module2) { "use strict"; var utils = require_utils(); var bind = require_bind(); @@ -12344,9 +12344,9 @@ var require_axios = __commonJS({ } }); -// node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/index.js +// node_modules/.pnpm/axios@0.27.2/node_modules/axios/index.js var require_axios2 = __commonJS({ - "node_modules/.pnpm/axios@0.27.2_debug@4.3.4/node_modules/axios/index.js"(exports, module2) { + "node_modules/.pnpm/axios@0.27.2/node_modules/axios/index.js"(exports, module2) { module2.exports = require_axios(); } }); @@ -12571,215 +12571,6 @@ var require_bella = __commonJS({ } }); -// node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/named-references.js -var require_named_references = __commonJS({ - "node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/named-references.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.bodyRegExps = { xml: /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g, html4: /&(?:nbsp|iexcl|cent|pound|curren|yen|brvbar|sect|uml|copy|ordf|laquo|not|shy|reg|macr|deg|plusmn|sup2|sup3|acute|micro|para|middot|cedil|sup1|ordm|raquo|frac14|frac12|frac34|iquest|Agrave|Aacute|Acirc|Atilde|Auml|Aring|AElig|Ccedil|Egrave|Eacute|Ecirc|Euml|Igrave|Iacute|Icirc|Iuml|ETH|Ntilde|Ograve|Oacute|Ocirc|Otilde|Ouml|times|Oslash|Ugrave|Uacute|Ucirc|Uuml|Yacute|THORN|szlig|agrave|aacute|acirc|atilde|auml|aring|aelig|ccedil|egrave|eacute|ecirc|euml|igrave|iacute|icirc|iuml|eth|ntilde|ograve|oacute|ocirc|otilde|ouml|divide|oslash|ugrave|uacute|ucirc|uuml|yacute|thorn|yuml|quot|amp|lt|gt|#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g, html5: /&(?:AElig|AMP|Aacute|Acirc|Agrave|Aring|Atilde|Auml|COPY|Ccedil|ETH|Eacute|Ecirc|Egrave|Euml|GT|Iacute|Icirc|Igrave|Iuml|LT|Ntilde|Oacute|Ocirc|Ograve|Oslash|Otilde|Ouml|QUOT|REG|THORN|Uacute|Ucirc|Ugrave|Uuml|Yacute|aacute|acirc|acute|aelig|agrave|amp|aring|atilde|auml|brvbar|ccedil|cedil|cent|copy|curren|deg|divide|eacute|ecirc|egrave|eth|euml|frac12|frac14|frac34|gt|iacute|icirc|iexcl|igrave|iquest|iuml|laquo|lt|macr|micro|middot|nbsp|not|ntilde|oacute|ocirc|ograve|ordf|ordm|oslash|otilde|ouml|para|plusmn|pound|quot|raquo|reg|sect|shy|sup1|sup2|sup3|szlig|thorn|times|uacute|ucirc|ugrave|uml|uuml|yacute|yen|yuml|#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g }; - exports.namedReferences = { xml: { entities: { "<": "<", ">": ">", """: '"', "'": "'", "&": "&" }, characters: { "<": "<", ">": ">", '"': """, "'": "'", "&": "&" } }, html4: { entities: { "'": "'", " ": " ", " ": " ", "¡": "¡", "¡": "¡", "¢": "¢", "¢": "¢", "£": "£", "£": "£", "¤": "¤", "¤": "¤", "¥": "¥", "¥": "¥", "¦": "¦", "¦": "¦", "§": "§", "§": "§", "¨": "¨", "¨": "¨", "©": "©", "©": "©", "ª": "ª", "ª": "ª", "«": "«", "«": "«", "¬": "¬", "¬": "¬", "­": "­", "­": "­", "®": "®", "®": "®", "¯": "¯", "¯": "¯", "°": "°", "°": "°", "±": "±", "±": "±", "²": "²", "²": "²", "³": "³", "³": "³", "´": "´", "´": "´", "µ": "µ", "µ": "µ", "¶": "¶", "¶": "¶", "·": "·", "·": "·", "¸": "¸", "¸": "¸", "¹": "¹", "¹": "¹", "º": "º", "º": "º", "»": "»", "»": "»", "¼": "¼", "¼": "¼", "½": "½", "½": "½", "¾": "¾", "¾": "¾", "¿": "¿", "¿": "¿", "À": "À", "À": "À", "Á": "Á", "Á": "Á", "Â": "Â", "Â": "Â", "Ã": "Ã", "Ã": "Ã", "Ä": "Ä", "Ä": "Ä", "Å": "Å", "Å": "Å", "Æ": "Æ", "Æ": "Æ", "Ç": "Ç", "Ç": "Ç", "È": "È", "È": "È", "É": "É", "É": "É", "Ê": "Ê", "Ê": "Ê", "Ë": "Ë", "Ë": "Ë", "Ì": "Ì", "Ì": "Ì", "Í": "Í", "Í": "Í", "Î": "Î", "Î": "Î", "Ï": "Ï", "Ï": "Ï", "Ð": "Ð", "Ð": "Ð", "Ñ": "Ñ", "Ñ": "Ñ", "Ò": "Ò", "Ò": "Ò", "Ó": "Ó", "Ó": "Ó", "Ô": "Ô", "Ô": "Ô", "Õ": "Õ", "Õ": "Õ", "Ö": "Ö", "Ö": "Ö", "×": "×", "×": "×", "Ø": "Ø", "Ø": "Ø", "Ù": "Ù", "Ù": "Ù", "Ú": "Ú", "Ú": "Ú", "Û": "Û", "Û": "Û", "Ü": "Ü", "Ü": "Ü", "Ý": "Ý", "Ý": "Ý", "Þ": "Þ", "Þ": "Þ", "ß": "ß", "ß": "ß", "à": "à", "à": "à", "á": "á", "á": "á", "â": "â", "â": "â", "ã": "ã", "ã": "ã", "ä": "ä", "ä": "ä", "å": "å", "å": "å", "æ": "æ", "æ": "æ", "ç": "ç", "ç": "ç", "è": "è", "è": "è", "é": "é", "é": "é", "ê": "ê", "ê": "ê", "ë": "ë", "ë": "ë", "ì": "ì", "ì": "ì", "í": "í", "í": "í", "î": "î", "î": "î", "ï": "ï", "ï": "ï", "ð": "ð", "ð": "ð", "ñ": "ñ", "ñ": "ñ", "ò": "ò", "ò": "ò", "ó": "ó", "ó": "ó", "ô": "ô", "ô": "ô", "õ": "õ", "õ": "õ", "ö": "ö", "ö": "ö", "÷": "÷", "÷": "÷", "ø": "ø", "ø": "ø", "ù": "ù", "ù": "ù", "ú": "ú", "ú": "ú", "û": "û", "û": "û", "ü": "ü", "ü": "ü", "ý": "ý", "ý": "ý", "þ": "þ", "þ": "þ", "ÿ": "ÿ", "ÿ": "ÿ", """: '"', """: '"', "&": "&", "&": "&", "<": "<", "<": "<", ">": ">", ">": ">", "Œ": "Œ", "œ": "œ", "Š": "Š", "š": "š", "Ÿ": "Ÿ", "ˆ": "ˆ", "˜": "˜", " ": " ", " ": " ", " ": " ", "‌": "‌", "‍": "‍", "‎": "‎", "‏": "‏", "–": "–", "—": "—", "‘": "‘", "’": "’", "‚": "‚", "“": "“", "”": "”", "„": "„", "†": "†", "‡": "‡", "‰": "‰", "‹": "‹", "›": "›", "€": "€", "ƒ": "ƒ", "Α": "Α", "Β": "Β", "Γ": "Γ", "Δ": "Δ", "Ε": "Ε", "Ζ": "Ζ", "Η": "Η", "Θ": "Θ", "Ι": "Ι", "Κ": "Κ", "Λ": "Λ", "Μ": "Μ", "Ν": "Ν", "Ξ": "Ξ", "Ο": "Ο", "Π": "Π", "Ρ": "Ρ", "Σ": "Σ", "Τ": "Τ", "Υ": "Υ", "Φ": "Φ", "Χ": "Χ", "Ψ": "Ψ", "Ω": "Ω", "α": "α", "β": "β", "γ": "γ", "δ": "δ", "ε": "ε", "ζ": "ζ", "η": "η", "θ": "θ", "ι": "ι", "κ": "κ", "λ": "λ", "μ": "μ", "ν": "ν", "ξ": "ξ", "ο": "ο", "π": "π", "ρ": "ρ", "ς": "ς", "σ": "σ", "τ": "τ", "υ": "υ", "φ": "φ", "χ": "χ", "ψ": "ψ", "ω": "ω", "ϑ": "ϑ", "ϒ": "ϒ", "ϖ": "ϖ", "•": "•", "…": "…", "′": "′", "″": "″", "‾": "‾", "⁄": "⁄", "℘": "℘", "ℑ": "ℑ", "ℜ": "ℜ", "™": "™", "ℵ": "ℵ", "←": "←", "↑": "↑", "→": "→", "↓": "↓", "↔": "↔", "↵": "↵", "⇐": "⇐", "⇑": "⇑", "⇒": "⇒", "⇓": "⇓", "⇔": "⇔", "∀": "∀", "∂": "∂", "∃": "∃", "∅": "∅", "∇": "∇", "∈": "∈", "∉": "∉", "∋": "∋", "∏": "∏", "∑": "∑", "−": "−", "∗": "∗", "√": "√", "∝": "∝", "∞": "∞", "∠": "∠", "∧": "∧", "∨": "∨", "∩": "∩", "∪": "∪", "∫": "∫", "∴": "∴", "∼": "∼", "≅": "≅", "≈": "≈", "≠": "≠", "≡": "≡", "≤": "≤", "≥": "≥", "⊂": "⊂", "⊃": "⊃", "⊄": "⊄", "⊆": "⊆", "⊇": "⊇", "⊕": "⊕", "⊗": "⊗", "⊥": "⊥", "⋅": "⋅", "⌈": "⌈", "⌉": "⌉", "⌊": "⌊", "⌋": "⌋", "⟨": "〈", "⟩": "〉", "◊": "◊", "♠": "♠", "♣": "♣", "♥": "♥", "♦": "♦" }, characters: { "'": "'", " ": " ", "¡": "¡", "¢": "¢", "£": "£", "¤": "¤", "¥": "¥", "¦": "¦", "§": "§", "¨": "¨", "©": "©", "ª": "ª", "«": "«", "¬": "¬", "­": "­", "®": "®", "¯": "¯", "°": "°", "±": "±", "²": "²", "³": "³", "´": "´", "µ": "µ", "¶": "¶", "·": "·", "¸": "¸", "¹": "¹", "º": "º", "»": "»", "¼": "¼", "½": "½", "¾": "¾", "¿": "¿", "À": "À", "Á": "Á", "Â": "Â", "Ã": "Ã", "Ä": "Ä", "Å": "Å", "Æ": "Æ", "Ç": "Ç", "È": "È", "É": "É", "Ê": "Ê", "Ë": "Ë", "Ì": "Ì", "Í": "Í", "Î": "Î", "Ï": "Ï", "Ð": "Ð", "Ñ": "Ñ", "Ò": "Ò", "Ó": "Ó", "Ô": "Ô", "Õ": "Õ", "Ö": "Ö", "×": "×", "Ø": "Ø", "Ù": "Ù", "Ú": "Ú", "Û": "Û", "Ü": "Ü", "Ý": "Ý", "Þ": "Þ", "ß": "ß", "à": "à", "á": "á", "â": "â", "ã": "ã", "ä": "ä", "å": "å", "æ": "æ", "ç": "ç", "è": "è", "é": "é", "ê": "ê", "ë": "ë", "ì": "ì", "í": "í", "î": "î", "ï": "ï", "ð": "ð", "ñ": "ñ", "ò": "ò", "ó": "ó", "ô": "ô", "õ": "õ", "ö": "ö", "÷": "÷", "ø": "ø", "ù": "ù", "ú": "ú", "û": "û", "ü": "ü", "ý": "ý", "þ": "þ", "ÿ": "ÿ", '"': """, "&": "&", "<": "<", ">": ">", "Œ": "Œ", "œ": "œ", "Š": "Š", "š": "š", "Ÿ": "Ÿ", "ˆ": "ˆ", "˜": "˜", " ": " ", " ": " ", " ": " ", "‌": "‌", "‍": "‍", "‎": "‎", "‏": "‏", "–": "–", "—": "—", "‘": "‘", "’": "’", "‚": "‚", "“": "“", "”": "”", "„": "„", "†": "†", "‡": "‡", "‰": "‰", "‹": "‹", "›": "›", "€": "€", "ƒ": "ƒ", "Α": "Α", "Β": "Β", "Γ": "Γ", "Δ": "Δ", "Ε": "Ε", "Ζ": "Ζ", "Η": "Η", "Θ": "Θ", "Ι": "Ι", "Κ": "Κ", "Λ": "Λ", "Μ": "Μ", "Ν": "Ν", "Ξ": "Ξ", "Ο": "Ο", "Π": "Π", "Ρ": "Ρ", "Σ": "Σ", "Τ": "Τ", "Υ": "Υ", "Φ": "Φ", "Χ": "Χ", "Ψ": "Ψ", "Ω": "Ω", "α": "α", "β": "β", "γ": "γ", "δ": "δ", "ε": "ε", "ζ": "ζ", "η": "η", "θ": "θ", "ι": "ι", "κ": "κ", "λ": "λ", "μ": "μ", "ν": "ν", "ξ": "ξ", "ο": "ο", "π": "π", "ρ": "ρ", "ς": "ς", "σ": "σ", "τ": "τ", "υ": "υ", "φ": "φ", "χ": "χ", "ψ": "ψ", "ω": "ω", "ϑ": "ϑ", "ϒ": "ϒ", "ϖ": "ϖ", "•": "•", "…": "…", "′": "′", "″": "″", "‾": "‾", "⁄": "⁄", "℘": "℘", "ℑ": "ℑ", "ℜ": "ℜ", "™": "™", "ℵ": "ℵ", "←": "←", "↑": "↑", "→": "→", "↓": "↓", "↔": "↔", "↵": "↵", "⇐": "⇐", "⇑": "⇑", "⇒": "⇒", "⇓": "⇓", "⇔": "⇔", "∀": "∀", "∂": "∂", "∃": "∃", "∅": "∅", "∇": "∇", "∈": "∈", "∉": "∉", "∋": "∋", "∏": "∏", "∑": "∑", "−": "−", "∗": "∗", "√": "√", "∝": "∝", "∞": "∞", "∠": "∠", "∧": "∧", "∨": "∨", "∩": "∩", "∪": "∪", "∫": "∫", "∴": "∴", "∼": "∼", "≅": "≅", "≈": "≈", "≠": "≠", "≡": "≡", "≤": "≤", "≥": "≥", "⊂": "⊂", "⊃": "⊃", "⊄": "⊄", "⊆": "⊆", "⊇": "⊇", "⊕": "⊕", "⊗": "⊗", "⊥": "⊥", "⋅": "⋅", "⌈": "⌈", "⌉": "⌉", "⌊": "⌊", "⌋": "⌋", "〈": "⟨", "〉": "⟩", "◊": "◊", "♠": "♠", "♣": "♣", "♥": "♥", "♦": "♦" } }, html5: { entities: { "Æ": "Æ", "Æ": "Æ", "&": "&", "&": "&", "Á": "Á", "Á": "Á", "Ă": "Ă", "Â": "Â", "Â": "Â", "А": "А", "𝔄": "𝔄", "À": "À", "À": "À", "Α": "Α", "Ā": "Ā", "⩓": "⩓", "Ą": "Ą", "𝔸": "𝔸", "⁡": "⁡", "Å": "Å", "Å": "Å", "𝒜": "𝒜", "≔": "≔", "Ã": "Ã", "Ã": "Ã", "Ä": "Ä", "Ä": "Ä", "∖": "∖", "⫧": "⫧", "⌆": "⌆", "Б": "Б", "∵": "∵", "ℬ": "ℬ", "Β": "Β", "𝔅": "𝔅", "𝔹": "𝔹", "˘": "˘", "ℬ": "ℬ", "≎": "≎", "Ч": "Ч", "©": "©", "©": "©", "Ć": "Ć", "⋒": "⋒", "ⅅ": "ⅅ", "ℭ": "ℭ", "Č": "Č", "Ç": "Ç", "Ç": "Ç", "Ĉ": "Ĉ", "∰": "∰", "Ċ": "Ċ", "¸": "¸", "·": "·", "ℭ": "ℭ", "Χ": "Χ", "⊙": "⊙", "⊖": "⊖", "⊕": "⊕", "⊗": "⊗", "∲": "∲", "”": "”", "’": "’", "∷": "∷", "⩴": "⩴", "≡": "≡", "∯": "∯", "∮": "∮", "ℂ": "ℂ", "∐": "∐", "∳": "∳", "⨯": "⨯", "𝒞": "𝒞", "⋓": "⋓", "≍": "≍", "ⅅ": "ⅅ", "⤑": "⤑", "Ђ": "Ђ", "Ѕ": "Ѕ", "Џ": "Џ", "‡": "‡", "↡": "↡", "⫤": "⫤", "Ď": "Ď", "Д": "Д", "∇": "∇", "Δ": "Δ", "𝔇": "𝔇", "´": "´", "˙": "˙", "˝": "˝", "`": "`", "˜": "˜", "⋄": "⋄", "ⅆ": "ⅆ", "𝔻": "𝔻", "¨": "¨", "⃜": "⃜", "≐": "≐", "∯": "∯", "¨": "¨", "⇓": "⇓", "⇐": "⇐", "⇔": "⇔", "⫤": "⫤", "⟸": "⟸", "⟺": "⟺", "⟹": "⟹", "⇒": "⇒", "⊨": "⊨", "⇑": "⇑", "⇕": "⇕", "∥": "∥", "↓": "↓", "⤓": "⤓", "⇵": "⇵", "̑": "̑", "⥐": "⥐", "⥞": "⥞", "↽": "↽", "⥖": "⥖", "⥟": "⥟", "⇁": "⇁", "⥗": "⥗", "⊤": "⊤", "↧": "↧", "⇓": "⇓", "𝒟": "𝒟", "Đ": "Đ", "Ŋ": "Ŋ", "Ð": "Ð", "Ð": "Ð", "É": "É", "É": "É", "Ě": "Ě", "Ê": "Ê", "Ê": "Ê", "Э": "Э", "Ė": "Ė", "𝔈": "𝔈", "È": "È", "È": "È", "∈": "∈", "Ē": "Ē", "◻": "◻", "▫": "▫", "Ę": "Ę", "𝔼": "𝔼", "Ε": "Ε", "⩵": "⩵", "≂": "≂", "⇌": "⇌", "ℰ": "ℰ", "⩳": "⩳", "Η": "Η", "Ë": "Ë", "Ë": "Ë", "∃": "∃", "ⅇ": "ⅇ", "Ф": "Ф", "𝔉": "𝔉", "◼": "◼", "▪": "▪", "𝔽": "𝔽", "∀": "∀", "ℱ": "ℱ", "ℱ": "ℱ", "Ѓ": "Ѓ", ">": ">", ">": ">", "Γ": "Γ", "Ϝ": "Ϝ", "Ğ": "Ğ", "Ģ": "Ģ", "Ĝ": "Ĝ", "Г": "Г", "Ġ": "Ġ", "𝔊": "𝔊", "⋙": "⋙", "𝔾": "𝔾", "≥": "≥", "⋛": "⋛", "≧": "≧", "⪢": "⪢", "≷": "≷", "⩾": "⩾", "≳": "≳", "𝒢": "𝒢", "≫": "≫", "Ъ": "Ъ", "ˇ": "ˇ", "^": "^", "Ĥ": "Ĥ", "ℌ": "ℌ", "ℋ": "ℋ", "ℍ": "ℍ", "─": "─", "ℋ": "ℋ", "Ħ": "Ħ", "≎": "≎", "≏": "≏", "Е": "Е", "IJ": "IJ", "Ё": "Ё", "Í": "Í", "Í": "Í", "Î": "Î", "Î": "Î", "И": "И", "İ": "İ", "ℑ": "ℑ", "Ì": "Ì", "Ì": "Ì", "ℑ": "ℑ", "Ī": "Ī", "ⅈ": "ⅈ", "⇒": "⇒", "∬": "∬", "∫": "∫", "⋂": "⋂", "⁣": "⁣", "⁢": "⁢", "Į": "Į", "𝕀": "𝕀", "Ι": "Ι", "ℐ": "ℐ", "Ĩ": "Ĩ", "І": "І", "Ï": "Ï", "Ï": "Ï", "Ĵ": "Ĵ", "Й": "Й", "𝔍": "𝔍", "𝕁": "𝕁", "𝒥": "𝒥", "Ј": "Ј", "Є": "Є", "Х": "Х", "Ќ": "Ќ", "Κ": "Κ", "Ķ": "Ķ", "К": "К", "𝔎": "𝔎", "𝕂": "𝕂", "𝒦": "𝒦", "Љ": "Љ", "<": "<", "<": "<", "Ĺ": "Ĺ", "Λ": "Λ", "⟪": "⟪", "ℒ": "ℒ", "↞": "↞", "Ľ": "Ľ", "Ļ": "Ļ", "Л": "Л", "⟨": "⟨", "←": "←", "⇤": "⇤", "⇆": "⇆", "⌈": "⌈", "⟦": "⟦", "⥡": "⥡", "⇃": "⇃", "⥙": "⥙", "⌊": "⌊", "↔": "↔", "⥎": "⥎", "⊣": "⊣", "↤": "↤", "⥚": "⥚", "⊲": "⊲", "⧏": "⧏", "⊴": "⊴", "⥑": "⥑", "⥠": "⥠", "↿": "↿", "⥘": "⥘", "↼": "↼", "⥒": "⥒", "⇐": "⇐", "⇔": "⇔", "⋚": "⋚", "≦": "≦", "≶": "≶", "⪡": "⪡", "⩽": "⩽", "≲": "≲", "𝔏": "𝔏", "⋘": "⋘", "⇚": "⇚", "Ŀ": "Ŀ", "⟵": "⟵", "⟷": "⟷", "⟶": "⟶", "⟸": "⟸", "⟺": "⟺", "⟹": "⟹", "𝕃": "𝕃", "↙": "↙", "↘": "↘", "ℒ": "ℒ", "↰": "↰", "Ł": "Ł", "≪": "≪", "⤅": "⤅", "М": "М", " ": " ", "ℳ": "ℳ", "𝔐": "𝔐", "∓": "∓", "𝕄": "𝕄", "ℳ": "ℳ", "Μ": "Μ", "Њ": "Њ", "Ń": "Ń", "Ň": "Ň", "Ņ": "Ņ", "Н": "Н", "​": "​", "​": "​", "​": "​", "​": "​", "≫": "≫", "≪": "≪", " ": "\n", "𝔑": "𝔑", "⁠": "⁠", " ": " ", "ℕ": "ℕ", "⫬": "⫬", "≢": "≢", "≭": "≭", "∦": "∦", "∉": "∉", "≠": "≠", "≂̸": "≂̸", "∄": "∄", "≯": "≯", "≱": "≱", "≧̸": "≧̸", "≫̸": "≫̸", "≹": "≹", "⩾̸": "⩾̸", "≵": "≵", "≎̸": "≎̸", "≏̸": "≏̸", "⋪": "⋪", "⧏̸": "⧏̸", "⋬": "⋬", "≮": "≮", "≰": "≰", "≸": "≸", "≪̸": "≪̸", "⩽̸": "⩽̸", "≴": "≴", "⪢̸": "⪢̸", "⪡̸": "⪡̸", "⊀": "⊀", "⪯̸": "⪯̸", "⋠": "⋠", "∌": "∌", "⋫": "⋫", "⧐̸": "⧐̸", "⋭": "⋭", "⊏̸": "⊏̸", "⋢": "⋢", "⊐̸": "⊐̸", "⋣": "⋣", "⊂⃒": "⊂⃒", "⊈": "⊈", "⊁": "⊁", "⪰̸": "⪰̸", "⋡": "⋡", "≿̸": "≿̸", "⊃⃒": "⊃⃒", "⊉": "⊉", "≁": "≁", "≄": "≄", "≇": "≇", "≉": "≉", "∤": "∤", "𝒩": "𝒩", "Ñ": "Ñ", "Ñ": "Ñ", "Ν": "Ν", "Œ": "Œ", "Ó": "Ó", "Ó": "Ó", "Ô": "Ô", "Ô": "Ô", "О": "О", "Ő": "Ő", "𝔒": "𝔒", "Ò": "Ò", "Ò": "Ò", "Ō": "Ō", "Ω": "Ω", "Ο": "Ο", "𝕆": "𝕆", "“": "“", "‘": "‘", "⩔": "⩔", "𝒪": "𝒪", "Ø": "Ø", "Ø": "Ø", "Õ": "Õ", "Õ": "Õ", "⨷": "⨷", "Ö": "Ö", "Ö": "Ö", "‾": "‾", "⏞": "⏞", "⎴": "⎴", "⏜": "⏜", "∂": "∂", "П": "П", "𝔓": "𝔓", "Φ": "Φ", "Π": "Π", "±": "±", "ℌ": "ℌ", "ℙ": "ℙ", "⪻": "⪻", "≺": "≺", "⪯": "⪯", "≼": "≼", "≾": "≾", "″": "″", "∏": "∏", "∷": "∷", "∝": "∝", "𝒫": "𝒫", "Ψ": "Ψ", """: '"', """: '"', "𝔔": "𝔔", "ℚ": "ℚ", "𝒬": "𝒬", "⤐": "⤐", "®": "®", "®": "®", "Ŕ": "Ŕ", "⟫": "⟫", "↠": "↠", "⤖": "⤖", "Ř": "Ř", "Ŗ": "Ŗ", "Р": "Р", "ℜ": "ℜ", "∋": "∋", "⇋": "⇋", "⥯": "⥯", "ℜ": "ℜ", "Ρ": "Ρ", "⟩": "⟩", "→": "→", "⇥": "⇥", "⇄": "⇄", "⌉": "⌉", "⟧": "⟧", "⥝": "⥝", "⇂": "⇂", "⥕": "⥕", "⌋": "⌋", "⊢": "⊢", "↦": "↦", "⥛": "⥛", "⊳": "⊳", "⧐": "⧐", "⊵": "⊵", "⥏": "⥏", "⥜": "⥜", "↾": "↾", "⥔": "⥔", "⇀": "⇀", "⥓": "⥓", "⇒": "⇒", "ℝ": "ℝ", "⥰": "⥰", "⇛": "⇛", "ℛ": "ℛ", "↱": "↱", "⧴": "⧴", "Щ": "Щ", "Ш": "Ш", "Ь": "Ь", "Ś": "Ś", "⪼": "⪼", "Š": "Š", "Ş": "Ş", "Ŝ": "Ŝ", "С": "С", "𝔖": "𝔖", "↓": "↓", "←": "←", "→": "→", "↑": "↑", "Σ": "Σ", "∘": "∘", "𝕊": "𝕊", "√": "√", "□": "□", "⊓": "⊓", "⊏": "⊏", "⊑": "⊑", "⊐": "⊐", "⊒": "⊒", "⊔": "⊔", "𝒮": "𝒮", "⋆": "⋆", "⋐": "⋐", "⋐": "⋐", "⊆": "⊆", "≻": "≻", "⪰": "⪰", "≽": "≽", "≿": "≿", "∋": "∋", "∑": "∑", "⋑": "⋑", "⊃": "⊃", "⊇": "⊇", "⋑": "⋑", "Þ": "Þ", "Þ": "Þ", "™": "™", "Ћ": "Ћ", "Ц": "Ц", " ": " ", "Τ": "Τ", "Ť": "Ť", "Ţ": "Ţ", "Т": "Т", "𝔗": "𝔗", "∴": "∴", "Θ": "Θ", "  ": "  ", " ": " ", "∼": "∼", "≃": "≃", "≅": "≅", "≈": "≈", "𝕋": "𝕋", "⃛": "⃛", "𝒯": "𝒯", "Ŧ": "Ŧ", "Ú": "Ú", "Ú": "Ú", "↟": "↟", "⥉": "⥉", "Ў": "Ў", "Ŭ": "Ŭ", "Û": "Û", "Û": "Û", "У": "У", "Ű": "Ű", "𝔘": "𝔘", "Ù": "Ù", "Ù": "Ù", "Ū": "Ū", "_": "_", "⏟": "⏟", "⎵": "⎵", "⏝": "⏝", "⋃": "⋃", "⊎": "⊎", "Ų": "Ų", "𝕌": "𝕌", "↑": "↑", "⤒": "⤒", "⇅": "⇅", "↕": "↕", "⥮": "⥮", "⊥": "⊥", "↥": "↥", "⇑": "⇑", "⇕": "⇕", "↖": "↖", "↗": "↗", "ϒ": "ϒ", "Υ": "Υ", "Ů": "Ů", "𝒰": "𝒰", "Ũ": "Ũ", "Ü": "Ü", "Ü": "Ü", "⊫": "⊫", "⫫": "⫫", "В": "В", "⊩": "⊩", "⫦": "⫦", "⋁": "⋁", "‖": "‖", "‖": "‖", "∣": "∣", "|": "|", "❘": "❘", "≀": "≀", " ": " ", "𝔙": "𝔙", "𝕍": "𝕍", "𝒱": "𝒱", "⊪": "⊪", "Ŵ": "Ŵ", "⋀": "⋀", "𝔚": "𝔚", "𝕎": "𝕎", "𝒲": "𝒲", "𝔛": "𝔛", "Ξ": "Ξ", "𝕏": "𝕏", "𝒳": "𝒳", "Я": "Я", "Ї": "Ї", "Ю": "Ю", "Ý": "Ý", "Ý": "Ý", "Ŷ": "Ŷ", "Ы": "Ы", "𝔜": "𝔜", "𝕐": "𝕐", "𝒴": "𝒴", "Ÿ": "Ÿ", "Ж": "Ж", "Ź": "Ź", "Ž": "Ž", "З": "З", "Ż": "Ż", "​": "​", "Ζ": "Ζ", "ℨ": "ℨ", "ℤ": "ℤ", "𝒵": "𝒵", "á": "á", "á": "á", "ă": "ă", "∾": "∾", "∾̳": "∾̳", "∿": "∿", "â": "â", "â": "â", "´": "´", "´": "´", "а": "а", "æ": "æ", "æ": "æ", "⁡": "⁡", "𝔞": "𝔞", "à": "à", "à": "à", "ℵ": "ℵ", "ℵ": "ℵ", "α": "α", "ā": "ā", "⨿": "⨿", "&": "&", "&": "&", "∧": "∧", "⩕": "⩕", "⩜": "⩜", "⩘": "⩘", "⩚": "⩚", "∠": "∠", "⦤": "⦤", "∠": "∠", "∡": "∡", "⦨": "⦨", "⦩": "⦩", "⦪": "⦪", "⦫": "⦫", "⦬": "⦬", "⦭": "⦭", "⦮": "⦮", "⦯": "⦯", "∟": "∟", "⊾": "⊾", "⦝": "⦝", "∢": "∢", "Å": "Å", "⍼": "⍼", "ą": "ą", "𝕒": "𝕒", "≈": "≈", "⩰": "⩰", "⩯": "⩯", "≊": "≊", "≋": "≋", "'": "'", "≈": "≈", "≊": "≊", "å": "å", "å": "å", "𝒶": "𝒶", "*": "*", "≈": "≈", "≍": "≍", "ã": "ã", "ã": "ã", "ä": "ä", "ä": "ä", "∳": "∳", "⨑": "⨑", "⫭": "⫭", "≌": "≌", "϶": "϶", "‵": "‵", "∽": "∽", "⋍": "⋍", "⊽": "⊽", "⌅": "⌅", "⌅": "⌅", "⎵": "⎵", "⎶": "⎶", "≌": "≌", "б": "б", "„": "„", "∵": "∵", "∵": "∵", "⦰": "⦰", "϶": "϶", "ℬ": "ℬ", "β": "β", "ℶ": "ℶ", "≬": "≬", "𝔟": "𝔟", "⋂": "⋂", "◯": "◯", "⋃": "⋃", "⨀": "⨀", "⨁": "⨁", "⨂": "⨂", "⨆": "⨆", "★": "★", "▽": "▽", "△": "△", "⨄": "⨄", "⋁": "⋁", "⋀": "⋀", "⤍": "⤍", "⧫": "⧫", "▪": "▪", "▴": "▴", "▾": "▾", "◂": "◂", "▸": "▸", "␣": "␣", "▒": "▒", "░": "░", "▓": "▓", "█": "█", "=⃥": "=⃥", "≡⃥": "≡⃥", "⌐": "⌐", "𝕓": "𝕓", "⊥": "⊥", "⊥": "⊥", "⋈": "⋈", "╗": "╗", "╔": "╔", "╖": "╖", "╓": "╓", "═": "═", "╦": "╦", "╩": "╩", "╤": "╤", "╧": "╧", "╝": "╝", "╚": "╚", "╜": "╜", "╙": "╙", "║": "║", "╬": "╬", "╣": "╣", "╠": "╠", "╫": "╫", "╢": "╢", "╟": "╟", "⧉": "⧉", "╕": "╕", "╒": "╒", "┐": "┐", "┌": "┌", "─": "─", "╥": "╥", "╨": "╨", "┬": "┬", "┴": "┴", "⊟": "⊟", "⊞": "⊞", "⊠": "⊠", "╛": "╛", "╘": "╘", "┘": "┘", "└": "└", "│": "│", "╪": "╪", "╡": "╡", "╞": "╞", "┼": "┼", "┤": "┤", "├": "├", "‵": "‵", "˘": "˘", "¦": "¦", "¦": "¦", "𝒷": "𝒷", "⁏": "⁏", "∽": "∽", "⋍": "⋍", "\": "\\", "⧅": "⧅", "⟈": "⟈", "•": "•", "•": "•", "≎": "≎", "⪮": "⪮", "≏": "≏", "≏": "≏", "ć": "ć", "∩": "∩", "⩄": "⩄", "⩉": "⩉", "⩋": "⩋", "⩇": "⩇", "⩀": "⩀", "∩︀": "∩︀", "⁁": "⁁", "ˇ": "ˇ", "⩍": "⩍", "č": "č", "ç": "ç", "ç": "ç", "ĉ": "ĉ", "⩌": "⩌", "⩐": "⩐", "ċ": "ċ", "¸": "¸", "¸": "¸", "⦲": "⦲", "¢": "¢", "¢": "¢", "·": "·", "𝔠": "𝔠", "ч": "ч", "✓": "✓", "✓": "✓", "χ": "χ", "○": "○", "⧃": "⧃", "ˆ": "ˆ", "≗": "≗", "↺": "↺", "↻": "↻", "®": "®", "Ⓢ": "Ⓢ", "⊛": "⊛", "⊚": "⊚", "⊝": "⊝", "≗": "≗", "⨐": "⨐", "⫯": "⫯", "⧂": "⧂", "♣": "♣", "♣": "♣", ":": ":", "≔": "≔", "≔": "≔", ",": ",", "@": "@", "∁": "∁", "∘": "∘", "∁": "∁", "ℂ": "ℂ", "≅": "≅", "⩭": "⩭", "∮": "∮", "𝕔": "𝕔", "∐": "∐", "©": "©", "©": "©", "℗": "℗", "↵": "↵", "✗": "✗", "𝒸": "𝒸", "⫏": "⫏", "⫑": "⫑", "⫐": "⫐", "⫒": "⫒", "⋯": "⋯", "⤸": "⤸", "⤵": "⤵", "⋞": "⋞", "⋟": "⋟", "↶": "↶", "⤽": "⤽", "∪": "∪", "⩈": "⩈", "⩆": "⩆", "⩊": "⩊", "⊍": "⊍", "⩅": "⩅", "∪︀": "∪︀", "↷": "↷", "⤼": "⤼", "⋞": "⋞", "⋟": "⋟", "⋎": "⋎", "⋏": "⋏", "¤": "¤", "¤": "¤", "↶": "↶", "↷": "↷", "⋎": "⋎", "⋏": "⋏", "∲": "∲", "∱": "∱", "⌭": "⌭", "⇓": "⇓", "⥥": "⥥", "†": "†", "ℸ": "ℸ", "↓": "↓", "‐": "‐", "⊣": "⊣", "⤏": "⤏", "˝": "˝", "ď": "ď", "д": "д", "ⅆ": "ⅆ", "‡": "‡", "⇊": "⇊", "⩷": "⩷", "°": "°", "°": "°", "δ": "δ", "⦱": "⦱", "⥿": "⥿", "𝔡": "𝔡", "⇃": "⇃", "⇂": "⇂", "⋄": "⋄", "⋄": "⋄", "♦": "♦", "♦": "♦", "¨": "¨", "ϝ": "ϝ", "⋲": "⋲", "÷": "÷", "÷": "÷", "÷": "÷", "⋇": "⋇", "⋇": "⋇", "ђ": "ђ", "⌞": "⌞", "⌍": "⌍", "$": "$", "𝕕": "𝕕", "˙": "˙", "≐": "≐", "≑": "≑", "∸": "∸", "∔": "∔", "⊡": "⊡", "⌆": "⌆", "↓": "↓", "⇊": "⇊", "⇃": "⇃", "⇂": "⇂", "⤐": "⤐", "⌟": "⌟", "⌌": "⌌", "𝒹": "𝒹", "ѕ": "ѕ", "⧶": "⧶", "đ": "đ", "⋱": "⋱", "▿": "▿", "▾": "▾", "⇵": "⇵", "⥯": "⥯", "⦦": "⦦", "џ": "џ", "⟿": "⟿", "⩷": "⩷", "≑": "≑", "é": "é", "é": "é", "⩮": "⩮", "ě": "ě", "≖": "≖", "ê": "ê", "ê": "ê", "≕": "≕", "э": "э", "ė": "ė", "ⅇ": "ⅇ", "≒": "≒", "𝔢": "𝔢", "⪚": "⪚", "è": "è", "è": "è", "⪖": "⪖", "⪘": "⪘", "⪙": "⪙", "⏧": "⏧", "ℓ": "ℓ", "⪕": "⪕", "⪗": "⪗", "ē": "ē", "∅": "∅", "∅": "∅", "∅": "∅", " ": " ", " ": " ", " ": " ", "ŋ": "ŋ", " ": " ", "ę": "ę", "𝕖": "𝕖", "⋕": "⋕", "⧣": "⧣", "⩱": "⩱", "ε": "ε", "ε": "ε", "ϵ": "ϵ", "≖": "≖", "≕": "≕", "≂": "≂", "⪖": "⪖", "⪕": "⪕", "=": "=", "≟": "≟", "≡": "≡", "⩸": "⩸", "⧥": "⧥", "≓": "≓", "⥱": "⥱", "ℯ": "ℯ", "≐": "≐", "≂": "≂", "η": "η", "ð": "ð", "ð": "ð", "ë": "ë", "ë": "ë", "€": "€", "!": "!", "∃": "∃", "ℰ": "ℰ", "ⅇ": "ⅇ", "≒": "≒", "ф": "ф", "♀": "♀", "ffi": "ffi", "ff": "ff", "ffl": "ffl", "𝔣": "𝔣", "fi": "fi", "fj": "fj", "♭": "♭", "fl": "fl", "▱": "▱", "ƒ": "ƒ", "𝕗": "𝕗", "∀": "∀", "⋔": "⋔", "⫙": "⫙", "⨍": "⨍", "½": "½", "½": "½", "⅓": "⅓", "¼": "¼", "¼": "¼", "⅕": "⅕", "⅙": "⅙", "⅛": "⅛", "⅔": "⅔", "⅖": "⅖", "¾": "¾", "¾": "¾", "⅗": "⅗", "⅜": "⅜", "⅘": "⅘", "⅚": "⅚", "⅝": "⅝", "⅞": "⅞", "⁄": "⁄", "⌢": "⌢", "𝒻": "𝒻", "≧": "≧", "⪌": "⪌", "ǵ": "ǵ", "γ": "γ", "ϝ": "ϝ", "⪆": "⪆", "ğ": "ğ", "ĝ": "ĝ", "г": "г", "ġ": "ġ", "≥": "≥", "⋛": "⋛", "≥": "≥", "≧": "≧", "⩾": "⩾", "⩾": "⩾", "⪩": "⪩", "⪀": "⪀", "⪂": "⪂", "⪄": "⪄", "⋛︀": "⋛︀", "⪔": "⪔", "𝔤": "𝔤", "≫": "≫", "⋙": "⋙", "ℷ": "ℷ", "ѓ": "ѓ", "≷": "≷", "⪒": "⪒", "⪥": "⪥", "⪤": "⪤", "≩": "≩", "⪊": "⪊", "⪊": "⪊", "⪈": "⪈", "⪈": "⪈", "≩": "≩", "⋧": "⋧", "𝕘": "𝕘", "`": "`", "ℊ": "ℊ", "≳": "≳", "⪎": "⪎", "⪐": "⪐", ">": ">", ">": ">", "⪧": "⪧", "⩺": "⩺", "⋗": "⋗", "⦕": "⦕", "⩼": "⩼", "⪆": "⪆", "⥸": "⥸", "⋗": "⋗", "⋛": "⋛", "⪌": "⪌", "≷": "≷", "≳": "≳", "≩︀": "≩︀", "≩︀": "≩︀", "⇔": "⇔", " ": " ", "½": "½", "ℋ": "ℋ", "ъ": "ъ", "↔": "↔", "⥈": "⥈", "↭": "↭", "ℏ": "ℏ", "ĥ": "ĥ", "♥": "♥", "♥": "♥", "…": "…", "⊹": "⊹", "𝔥": "𝔥", "⤥": "⤥", "⤦": "⤦", "⇿": "⇿", "∻": "∻", "↩": "↩", "↪": "↪", "𝕙": "𝕙", "―": "―", "𝒽": "𝒽", "ℏ": "ℏ", "ħ": "ħ", "⁃": "⁃", "‐": "‐", "í": "í", "í": "í", "⁣": "⁣", "î": "î", "î": "î", "и": "и", "е": "е", "¡": "¡", "¡": "¡", "⇔": "⇔", "𝔦": "𝔦", "ì": "ì", "ì": "ì", "ⅈ": "ⅈ", "⨌": "⨌", "∭": "∭", "⧜": "⧜", "℩": "℩", "ij": "ij", "ī": "ī", "ℑ": "ℑ", "ℐ": "ℐ", "ℑ": "ℑ", "ı": "ı", "⊷": "⊷", "Ƶ": "Ƶ", "∈": "∈", "℅": "℅", "∞": "∞", "⧝": "⧝", "ı": "ı", "∫": "∫", "⊺": "⊺", "ℤ": "ℤ", "⊺": "⊺", "⨗": "⨗", "⨼": "⨼", "ё": "ё", "į": "į", "𝕚": "𝕚", "ι": "ι", "⨼": "⨼", "¿": "¿", "¿": "¿", "𝒾": "𝒾", "∈": "∈", "⋹": "⋹", "⋵": "⋵", "⋴": "⋴", "⋳": "⋳", "∈": "∈", "⁢": "⁢", "ĩ": "ĩ", "і": "і", "ï": "ï", "ï": "ï", "ĵ": "ĵ", "й": "й", "𝔧": "𝔧", "ȷ": "ȷ", "𝕛": "𝕛", "𝒿": "𝒿", "ј": "ј", "є": "є", "κ": "κ", "ϰ": "ϰ", "ķ": "ķ", "к": "к", "𝔨": "𝔨", "ĸ": "ĸ", "х": "х", "ќ": "ќ", "𝕜": "𝕜", "𝓀": "𝓀", "⇚": "⇚", "⇐": "⇐", "⤛": "⤛", "⤎": "⤎", "≦": "≦", "⪋": "⪋", "⥢": "⥢", "ĺ": "ĺ", "⦴": "⦴", "ℒ": "ℒ", "λ": "λ", "⟨": "⟨", "⦑": "⦑", "⟨": "⟨", "⪅": "⪅", "«": "«", "«": "«", "←": "←", "⇤": "⇤", "⤟": "⤟", "⤝": "⤝", "↩": "↩", "↫": "↫", "⤹": "⤹", "⥳": "⥳", "↢": "↢", "⪫": "⪫", "⤙": "⤙", "⪭": "⪭", "⪭︀": "⪭︀", "⤌": "⤌", "❲": "❲", "{": "{", "[": "[", "⦋": "⦋", "⦏": "⦏", "⦍": "⦍", "ľ": "ľ", "ļ": "ļ", "⌈": "⌈", "{": "{", "л": "л", "⤶": "⤶", "“": "“", "„": "„", "⥧": "⥧", "⥋": "⥋", "↲": "↲", "≤": "≤", "←": "←", "↢": "↢", "↽": "↽", "↼": "↼", "⇇": "⇇", "↔": "↔", "⇆": "⇆", "⇋": "⇋", "↭": "↭", "⋋": "⋋", "⋚": "⋚", "≤": "≤", "≦": "≦", "⩽": "⩽", "⩽": "⩽", "⪨": "⪨", "⩿": "⩿", "⪁": "⪁", "⪃": "⪃", "⋚︀": "⋚︀", "⪓": "⪓", "⪅": "⪅", "⋖": "⋖", "⋚": "⋚", "⪋": "⪋", "≶": "≶", "≲": "≲", "⥼": "⥼", "⌊": "⌊", "𝔩": "𝔩", "≶": "≶", "⪑": "⪑", "↽": "↽", "↼": "↼", "⥪": "⥪", "▄": "▄", "љ": "љ", "≪": "≪", "⇇": "⇇", "⌞": "⌞", "⥫": "⥫", "◺": "◺", "ŀ": "ŀ", "⎰": "⎰", "⎰": "⎰", "≨": "≨", "⪉": "⪉", "⪉": "⪉", "⪇": "⪇", "⪇": "⪇", "≨": "≨", "⋦": "⋦", "⟬": "⟬", "⇽": "⇽", "⟦": "⟦", "⟵": "⟵", "⟷": "⟷", "⟼": "⟼", "⟶": "⟶", "↫": "↫", "↬": "↬", "⦅": "⦅", "𝕝": "𝕝", "⨭": "⨭", "⨴": "⨴", "∗": "∗", "_": "_", "◊": "◊", "◊": "◊", "⧫": "⧫", "(": "(", "⦓": "⦓", "⇆": "⇆", "⌟": "⌟", "⇋": "⇋", "⥭": "⥭", "‎": "‎", "⊿": "⊿", "‹": "‹", "𝓁": "𝓁", "↰": "↰", "≲": "≲", "⪍": "⪍", "⪏": "⪏", "[": "[", "‘": "‘", "‚": "‚", "ł": "ł", "<": "<", "<": "<", "⪦": "⪦", "⩹": "⩹", "⋖": "⋖", "⋋": "⋋", "⋉": "⋉", "⥶": "⥶", "⩻": "⩻", "⦖": "⦖", "◃": "◃", "⊴": "⊴", "◂": "◂", "⥊": "⥊", "⥦": "⥦", "≨︀": "≨︀", "≨︀": "≨︀", "∺": "∺", "¯": "¯", "¯": "¯", "♂": "♂", "✠": "✠", "✠": "✠", "↦": "↦", "↦": "↦", "↧": "↧", "↤": "↤", "↥": "↥", "▮": "▮", "⨩": "⨩", "м": "м", "—": "—", "∡": "∡", "𝔪": "𝔪", "℧": "℧", "µ": "µ", "µ": "µ", "∣": "∣", "*": "*", "⫰": "⫰", "·": "·", "·": "·", "−": "−", "⊟": "⊟", "∸": "∸", "⨪": "⨪", "⫛": "⫛", "…": "…", "∓": "∓", "⊧": "⊧", "𝕞": "𝕞", "∓": "∓", "𝓂": "𝓂", "∾": "∾", "μ": "μ", "⊸": "⊸", "⊸": "⊸", "⋙̸": "⋙̸", "≫⃒": "≫⃒", "≫̸": "≫̸", "⇍": "⇍", "⇎": "⇎", "⋘̸": "⋘̸", "≪⃒": "≪⃒", "≪̸": "≪̸", "⇏": "⇏", "⊯": "⊯", "⊮": "⊮", "∇": "∇", "ń": "ń", "∠⃒": "∠⃒", "≉": "≉", "⩰̸": "⩰̸", "≋̸": "≋̸", "ʼn": "ʼn", "≉": "≉", "♮": "♮", "♮": "♮", "ℕ": "ℕ", " ": " ", " ": " ", "≎̸": "≎̸", "≏̸": "≏̸", "⩃": "⩃", "ň": "ň", "ņ": "ņ", "≇": "≇", "⩭̸": "⩭̸", "⩂": "⩂", "н": "н", "–": "–", "≠": "≠", "⇗": "⇗", "⤤": "⤤", "↗": "↗", "↗": "↗", "≐̸": "≐̸", "≢": "≢", "⤨": "⤨", "≂̸": "≂̸", "∄": "∄", "∄": "∄", "𝔫": "𝔫", "≧̸": "≧̸", "≱": "≱", "≱": "≱", "≧̸": "≧̸", "⩾̸": "⩾̸", "⩾̸": "⩾̸", "≵": "≵", "≯": "≯", "≯": "≯", "⇎": "⇎", "↮": "↮", "⫲": "⫲", "∋": "∋", "⋼": "⋼", "⋺": "⋺", "∋": "∋", "њ": "њ", "⇍": "⇍", "≦̸": "≦̸", "↚": "↚", "‥": "‥", "≰": "≰", "↚": "↚", "↮": "↮", "≰": "≰", "≦̸": "≦̸", "⩽̸": "⩽̸", "⩽̸": "⩽̸", "≮": "≮", "≴": "≴", "≮": "≮", "⋪": "⋪", "⋬": "⋬", "∤": "∤", "𝕟": "𝕟", "¬": "¬", "¬": "¬", "∉": "∉", "⋹̸": "⋹̸", "⋵̸": "⋵̸", "∉": "∉", "⋷": "⋷", "⋶": "⋶", "∌": "∌", "∌": "∌", "⋾": "⋾", "⋽": "⋽", "∦": "∦", "∦": "∦", "⫽⃥": "⫽⃥", "∂̸": "∂̸", "⨔": "⨔", "⊀": "⊀", "⋠": "⋠", "⪯̸": "⪯̸", "⊀": "⊀", "⪯̸": "⪯̸", "⇏": "⇏", "↛": "↛", "⤳̸": "⤳̸", "↝̸": "↝̸", "↛": "↛", "⋫": "⋫", "⋭": "⋭", "⊁": "⊁", "⋡": "⋡", "⪰̸": "⪰̸", "𝓃": "𝓃", "∤": "∤", "∦": "∦", "≁": "≁", "≄": "≄", "≄": "≄", "∤": "∤", "∦": "∦", "⋢": "⋢", "⋣": "⋣", "⊄": "⊄", "⫅̸": "⫅̸", "⊈": "⊈", "⊂⃒": "⊂⃒", "⊈": "⊈", "⫅̸": "⫅̸", "⊁": "⊁", "⪰̸": "⪰̸", "⊅": "⊅", "⫆̸": "⫆̸", "⊉": "⊉", "⊃⃒": "⊃⃒", "⊉": "⊉", "⫆̸": "⫆̸", "≹": "≹", "ñ": "ñ", "ñ": "ñ", "≸": "≸", "⋪": "⋪", "⋬": "⋬", "⋫": "⋫", "⋭": "⋭", "ν": "ν", "#": "#", "№": "№", " ": " ", "⊭": "⊭", "⤄": "⤄", "≍⃒": "≍⃒", "⊬": "⊬", "≥⃒": "≥⃒", ">⃒": ">⃒", "⧞": "⧞", "⤂": "⤂", "≤⃒": "≤⃒", "<⃒": "<⃒", "⊴⃒": "⊴⃒", "⤃": "⤃", "⊵⃒": "⊵⃒", "∼⃒": "∼⃒", "⇖": "⇖", "⤣": "⤣", "↖": "↖", "↖": "↖", "⤧": "⤧", "Ⓢ": "Ⓢ", "ó": "ó", "ó": "ó", "⊛": "⊛", "⊚": "⊚", "ô": "ô", "ô": "ô", "о": "о", "⊝": "⊝", "ő": "ő", "⨸": "⨸", "⊙": "⊙", "⦼": "⦼", "œ": "œ", "⦿": "⦿", "𝔬": "𝔬", "˛": "˛", "ò": "ò", "ò": "ò", "⧁": "⧁", "⦵": "⦵", "Ω": "Ω", "∮": "∮", "↺": "↺", "⦾": "⦾", "⦻": "⦻", "‾": "‾", "⧀": "⧀", "ō": "ō", "ω": "ω", "ο": "ο", "⦶": "⦶", "⊖": "⊖", "𝕠": "𝕠", "⦷": "⦷", "⦹": "⦹", "⊕": "⊕", "∨": "∨", "↻": "↻", "⩝": "⩝", "ℴ": "ℴ", "ℴ": "ℴ", "ª": "ª", "ª": "ª", "º": "º", "º": "º", "⊶": "⊶", "⩖": "⩖", "⩗": "⩗", "⩛": "⩛", "ℴ": "ℴ", "ø": "ø", "ø": "ø", "⊘": "⊘", "õ": "õ", "õ": "õ", "⊗": "⊗", "⨶": "⨶", "ö": "ö", "ö": "ö", "⌽": "⌽", "∥": "∥", "¶": "¶", "¶": "¶", "∥": "∥", "⫳": "⫳", "⫽": "⫽", "∂": "∂", "п": "п", "%": "%", ".": ".", "‰": "‰", "⊥": "⊥", "‱": "‱", "𝔭": "𝔭", "φ": "φ", "ϕ": "ϕ", "ℳ": "ℳ", "☎": "☎", "π": "π", "⋔": "⋔", "ϖ": "ϖ", "ℏ": "ℏ", "ℎ": "ℎ", "ℏ": "ℏ", "+": "+", "⨣": "⨣", "⊞": "⊞", "⨢": "⨢", "∔": "∔", "⨥": "⨥", "⩲": "⩲", "±": "±", "±": "±", "⨦": "⨦", "⨧": "⨧", "±": "±", "⨕": "⨕", "𝕡": "𝕡", "£": "£", "£": "£", "≺": "≺", "⪳": "⪳", "⪷": "⪷", "≼": "≼", "⪯": "⪯", "≺": "≺", "⪷": "⪷", "≼": "≼", "⪯": "⪯", "⪹": "⪹", "⪵": "⪵", "⋨": "⋨", "≾": "≾", "′": "′", "ℙ": "ℙ", "⪵": "⪵", "⪹": "⪹", "⋨": "⋨", "∏": "∏", "⌮": "⌮", "⌒": "⌒", "⌓": "⌓", "∝": "∝", "∝": "∝", "≾": "≾", "⊰": "⊰", "𝓅": "𝓅", "ψ": "ψ", " ": " ", "𝔮": "𝔮", "⨌": "⨌", "𝕢": "𝕢", "⁗": "⁗", "𝓆": "𝓆", "ℍ": "ℍ", "⨖": "⨖", "?": "?", "≟": "≟", """: '"', """: '"', "⇛": "⇛", "⇒": "⇒", "⤜": "⤜", "⤏": "⤏", "⥤": "⥤", "∽̱": "∽̱", "ŕ": "ŕ", "√": "√", "⦳": "⦳", "⟩": "⟩", "⦒": "⦒", "⦥": "⦥", "⟩": "⟩", "»": "»", "»": "»", "→": "→", "⥵": "⥵", "⇥": "⇥", "⤠": "⤠", "⤳": "⤳", "⤞": "⤞", "↪": "↪", "↬": "↬", "⥅": "⥅", "⥴": "⥴", "↣": "↣", "↝": "↝", "⤚": "⤚", "∶": "∶", "ℚ": "ℚ", "⤍": "⤍", "❳": "❳", "}": "}", "]": "]", "⦌": "⦌", "⦎": "⦎", "⦐": "⦐", "ř": "ř", "ŗ": "ŗ", "⌉": "⌉", "}": "}", "р": "р", "⤷": "⤷", "⥩": "⥩", "”": "”", "”": "”", "↳": "↳", "ℜ": "ℜ", "ℛ": "ℛ", "ℜ": "ℜ", "ℝ": "ℝ", "▭": "▭", "®": "®", "®": "®", "⥽": "⥽", "⌋": "⌋", "𝔯": "𝔯", "⇁": "⇁", "⇀": "⇀", "⥬": "⥬", "ρ": "ρ", "ϱ": "ϱ", "→": "→", "↣": "↣", "⇁": "⇁", "⇀": "⇀", "⇄": "⇄", "⇌": "⇌", "⇉": "⇉", "↝": "↝", "⋌": "⋌", "˚": "˚", "≓": "≓", "⇄": "⇄", "⇌": "⇌", "‏": "‏", "⎱": "⎱", "⎱": "⎱", "⫮": "⫮", "⟭": "⟭", "⇾": "⇾", "⟧": "⟧", "⦆": "⦆", "𝕣": "𝕣", "⨮": "⨮", "⨵": "⨵", ")": ")", "⦔": "⦔", "⨒": "⨒", "⇉": "⇉", "›": "›", "𝓇": "𝓇", "↱": "↱", "]": "]", "’": "’", "’": "’", "⋌": "⋌", "⋊": "⋊", "▹": "▹", "⊵": "⊵", "▸": "▸", "⧎": "⧎", "⥨": "⥨", "℞": "℞", "ś": "ś", "‚": "‚", "≻": "≻", "⪴": "⪴", "⪸": "⪸", "š": "š", "≽": "≽", "⪰": "⪰", "ş": "ş", "ŝ": "ŝ", "⪶": "⪶", "⪺": "⪺", "⋩": "⋩", "⨓": "⨓", "≿": "≿", "с": "с", "⋅": "⋅", "⊡": "⊡", "⩦": "⩦", "⇘": "⇘", "⤥": "⤥", "↘": "↘", "↘": "↘", "§": "§", "§": "§", ";": ";", "⤩": "⤩", "∖": "∖", "∖": "∖", "✶": "✶", "𝔰": "𝔰", "⌢": "⌢", "♯": "♯", "щ": "щ", "ш": "ш", "∣": "∣", "∥": "∥", "­": "­", "­": "­", "σ": "σ", "ς": "ς", "ς": "ς", "∼": "∼", "⩪": "⩪", "≃": "≃", "≃": "≃", "⪞": "⪞", "⪠": "⪠", "⪝": "⪝", "⪟": "⪟", "≆": "≆", "⨤": "⨤", "⥲": "⥲", "←": "←", "∖": "∖", "⨳": "⨳", "⧤": "⧤", "∣": "∣", "⌣": "⌣", "⪪": "⪪", "⪬": "⪬", "⪬︀": "⪬︀", "ь": "ь", "/": "/", "⧄": "⧄", "⌿": "⌿", "𝕤": "𝕤", "♠": "♠", "♠": "♠", "∥": "∥", "⊓": "⊓", "⊓︀": "⊓︀", "⊔": "⊔", "⊔︀": "⊔︀", "⊏": "⊏", "⊑": "⊑", "⊏": "⊏", "⊑": "⊑", "⊐": "⊐", "⊒": "⊒", "⊐": "⊐", "⊒": "⊒", "□": "□", "□": "□", "▪": "▪", "▪": "▪", "→": "→", "𝓈": "𝓈", "∖": "∖", "⌣": "⌣", "⋆": "⋆", "☆": "☆", "★": "★", "ϵ": "ϵ", "ϕ": "ϕ", "¯": "¯", "⊂": "⊂", "⫅": "⫅", "⪽": "⪽", "⊆": "⊆", "⫃": "⫃", "⫁": "⫁", "⫋": "⫋", "⊊": "⊊", "⪿": "⪿", "⥹": "⥹", "⊂": "⊂", "⊆": "⊆", "⫅": "⫅", "⊊": "⊊", "⫋": "⫋", "⫇": "⫇", "⫕": "⫕", "⫓": "⫓", "≻": "≻", "⪸": "⪸", "≽": "≽", "⪰": "⪰", "⪺": "⪺", "⪶": "⪶", "⋩": "⋩", "≿": "≿", "∑": "∑", "♪": "♪", "¹": "¹", "¹": "¹", "²": "²", "²": "²", "³": "³", "³": "³", "⊃": "⊃", "⫆": "⫆", "⪾": "⪾", "⫘": "⫘", "⊇": "⊇", "⫄": "⫄", "⟉": "⟉", "⫗": "⫗", "⥻": "⥻", "⫂": "⫂", "⫌": "⫌", "⊋": "⊋", "⫀": "⫀", "⊃": "⊃", "⊇": "⊇", "⫆": "⫆", "⊋": "⊋", "⫌": "⫌", "⫈": "⫈", "⫔": "⫔", "⫖": "⫖", "⇙": "⇙", "⤦": "⤦", "↙": "↙", "↙": "↙", "⤪": "⤪", "ß": "ß", "ß": "ß", "⌖": "⌖", "τ": "τ", "⎴": "⎴", "ť": "ť", "ţ": "ţ", "т": "т", "⃛": "⃛", "⌕": "⌕", "𝔱": "𝔱", "∴": "∴", "∴": "∴", "θ": "θ", "ϑ": "ϑ", "ϑ": "ϑ", "≈": "≈", "∼": "∼", " ": " ", "≈": "≈", "∼": "∼", "þ": "þ", "þ": "þ", "˜": "˜", "×": "×", "×": "×", "⊠": "⊠", "⨱": "⨱", "⨰": "⨰", "∭": "∭", "⤨": "⤨", "⊤": "⊤", "⌶": "⌶", "⫱": "⫱", "𝕥": "𝕥", "⫚": "⫚", "⤩": "⤩", "‴": "‴", "™": "™", "▵": "▵", "▿": "▿", "◃": "◃", "⊴": "⊴", "≜": "≜", "▹": "▹", "⊵": "⊵", "◬": "◬", "≜": "≜", "⨺": "⨺", "⨹": "⨹", "⧍": "⧍", "⨻": "⨻", "⏢": "⏢", "𝓉": "𝓉", "ц": "ц", "ћ": "ћ", "ŧ": "ŧ", "≬": "≬", "↞": "↞", "↠": "↠", "⇑": "⇑", "⥣": "⥣", "ú": "ú", "ú": "ú", "↑": "↑", "ў": "ў", "ŭ": "ŭ", "û": "û", "û": "û", "у": "у", "⇅": "⇅", "ű": "ű", "⥮": "⥮", "⥾": "⥾", "𝔲": "𝔲", "ù": "ù", "ù": "ù", "↿": "↿", "↾": "↾", "▀": "▀", "⌜": "⌜", "⌜": "⌜", "⌏": "⌏", "◸": "◸", "ū": "ū", "¨": "¨", "¨": "¨", "ų": "ų", "𝕦": "𝕦", "↑": "↑", "↕": "↕", "↿": "↿", "↾": "↾", "⊎": "⊎", "υ": "υ", "ϒ": "ϒ", "υ": "υ", "⇈": "⇈", "⌝": "⌝", "⌝": "⌝", "⌎": "⌎", "ů": "ů", "◹": "◹", "𝓊": "𝓊", "⋰": "⋰", "ũ": "ũ", "▵": "▵", "▴": "▴", "⇈": "⇈", "ü": "ü", "ü": "ü", "⦧": "⦧", "⇕": "⇕", "⫨": "⫨", "⫩": "⫩", "⊨": "⊨", "⦜": "⦜", "ϵ": "ϵ", "ϰ": "ϰ", "∅": "∅", "ϕ": "ϕ", "ϖ": "ϖ", "∝": "∝", "↕": "↕", "ϱ": "ϱ", "ς": "ς", "⊊︀": "⊊︀", "⫋︀": "⫋︀", "⊋︀": "⊋︀", "⫌︀": "⫌︀", "ϑ": "ϑ", "⊲": "⊲", "⊳": "⊳", "в": "в", "⊢": "⊢", "∨": "∨", "⊻": "⊻", "≚": "≚", "⋮": "⋮", "|": "|", "|": "|", "𝔳": "𝔳", "⊲": "⊲", "⊂⃒": "⊂⃒", "⊃⃒": "⊃⃒", "𝕧": "𝕧", "∝": "∝", "⊳": "⊳", "𝓋": "𝓋", "⫋︀": "⫋︀", "⊊︀": "⊊︀", "⫌︀": "⫌︀", "⊋︀": "⊋︀", "⦚": "⦚", "ŵ": "ŵ", "⩟": "⩟", "∧": "∧", "≙": "≙", "℘": "℘", "𝔴": "𝔴", "𝕨": "𝕨", "℘": "℘", "≀": "≀", "≀": "≀", "𝓌": "𝓌", "⋂": "⋂", "◯": "◯", "⋃": "⋃", "▽": "▽", "𝔵": "𝔵", "⟺": "⟺", "⟷": "⟷", "ξ": "ξ", "⟸": "⟸", "⟵": "⟵", "⟼": "⟼", "⋻": "⋻", "⨀": "⨀", "𝕩": "𝕩", "⨁": "⨁", "⨂": "⨂", "⟹": "⟹", "⟶": "⟶", "𝓍": "𝓍", "⨆": "⨆", "⨄": "⨄", "△": "△", "⋁": "⋁", "⋀": "⋀", "ý": "ý", "ý": "ý", "я": "я", "ŷ": "ŷ", "ы": "ы", "¥": "¥", "¥": "¥", "𝔶": "𝔶", "ї": "ї", "𝕪": "𝕪", "𝓎": "𝓎", "ю": "ю", "ÿ": "ÿ", "ÿ": "ÿ", "ź": "ź", "ž": "ž", "з": "з", "ż": "ż", "ℨ": "ℨ", "ζ": "ζ", "𝔷": "𝔷", "ж": "ж", "⇝": "⇝", "𝕫": "𝕫", "𝓏": "𝓏", "‍": "‍", "‌": "‌" }, characters: { "Æ": "Æ", "&": "&", "Á": "Á", "Ă": "Ă", "Â": "Â", "А": "А", "𝔄": "𝔄", "À": "À", "Α": "Α", "Ā": "Ā", "⩓": "⩓", "Ą": "Ą", "𝔸": "𝔸", "⁡": "⁡", "Å": "Å", "𝒜": "𝒜", "≔": "≔", "Ã": "Ã", "Ä": "Ä", "∖": "∖", "⫧": "⫧", "⌆": "⌆", "Б": "Б", "∵": "∵", "ℬ": "ℬ", "Β": "Β", "𝔅": "𝔅", "𝔹": "𝔹", "˘": "˘", "≎": "≎", "Ч": "Ч", "©": "©", "Ć": "Ć", "⋒": "⋒", "ⅅ": "ⅅ", "ℭ": "ℭ", "Č": "Č", "Ç": "Ç", "Ĉ": "Ĉ", "∰": "∰", "Ċ": "Ċ", "¸": "¸", "·": "·", "Χ": "Χ", "⊙": "⊙", "⊖": "⊖", "⊕": "⊕", "⊗": "⊗", "∲": "∲", "”": "”", "’": "’", "∷": "∷", "⩴": "⩴", "≡": "≡", "∯": "∯", "∮": "∮", "ℂ": "ℂ", "∐": "∐", "∳": "∳", "⨯": "⨯", "𝒞": "𝒞", "⋓": "⋓", "≍": "≍", "⤑": "⤑", "Ђ": "Ђ", "Ѕ": "Ѕ", "Џ": "Џ", "‡": "‡", "↡": "↡", "⫤": "⫤", "Ď": "Ď", "Д": "Д", "∇": "∇", "Δ": "Δ", "𝔇": "𝔇", "´": "´", "˙": "˙", "˝": "˝", "`": "`", "˜": "˜", "⋄": "⋄", "ⅆ": "ⅆ", "𝔻": "𝔻", "¨": "¨", "⃜": "⃜", "≐": "≐", "⇓": "⇓", "⇐": "⇐", "⇔": "⇔", "⟸": "⟸", "⟺": "⟺", "⟹": "⟹", "⇒": "⇒", "⊨": "⊨", "⇑": "⇑", "⇕": "⇕", "∥": "∥", "↓": "↓", "⤓": "⤓", "⇵": "⇵", "̑": "̑", "⥐": "⥐", "⥞": "⥞", "↽": "↽", "⥖": "⥖", "⥟": "⥟", "⇁": "⇁", "⥗": "⥗", "⊤": "⊤", "↧": "↧", "𝒟": "𝒟", "Đ": "Đ", "Ŋ": "Ŋ", "Ð": "Ð", "É": "É", "Ě": "Ě", "Ê": "Ê", "Э": "Э", "Ė": "Ė", "𝔈": "𝔈", "È": "È", "∈": "∈", "Ē": "Ē", "◻": "◻", "▫": "▫", "Ę": "Ę", "𝔼": "𝔼", "Ε": "Ε", "⩵": "⩵", "≂": "≂", "⇌": "⇌", "ℰ": "ℰ", "⩳": "⩳", "Η": "Η", "Ë": "Ë", "∃": "∃", "ⅇ": "ⅇ", "Ф": "Ф", "𝔉": "𝔉", "◼": "◼", "▪": "▪", "𝔽": "𝔽", "∀": "∀", "ℱ": "ℱ", "Ѓ": "Ѓ", ">": ">", "Γ": "Γ", "Ϝ": "Ϝ", "Ğ": "Ğ", "Ģ": "Ģ", "Ĝ": "Ĝ", "Г": "Г", "Ġ": "Ġ", "𝔊": "𝔊", "⋙": "⋙", "𝔾": "𝔾", "≥": "≥", "⋛": "⋛", "≧": "≧", "⪢": "⪢", "≷": "≷", "⩾": "⩾", "≳": "≳", "𝒢": "𝒢", "≫": "≫", "Ъ": "Ъ", "ˇ": "ˇ", "^": "^", "Ĥ": "Ĥ", "ℌ": "ℌ", "ℋ": "ℋ", "ℍ": "ℍ", "─": "─", "Ħ": "Ħ", "≏": "≏", "Е": "Е", "IJ": "IJ", "Ё": "Ё", "Í": "Í", "Î": "Î", "И": "И", "İ": "İ", "ℑ": "ℑ", "Ì": "Ì", "Ī": "Ī", "ⅈ": "ⅈ", "∬": "∬", "∫": "∫", "⋂": "⋂", "⁣": "⁣", "⁢": "⁢", "Į": "Į", "𝕀": "𝕀", "Ι": "Ι", "ℐ": "ℐ", "Ĩ": "Ĩ", "І": "І", "Ï": "Ï", "Ĵ": "Ĵ", "Й": "Й", "𝔍": "𝔍", "𝕁": "𝕁", "𝒥": "𝒥", "Ј": "Ј", "Є": "Є", "Х": "Х", "Ќ": "Ќ", "Κ": "Κ", "Ķ": "Ķ", "К": "К", "𝔎": "𝔎", "𝕂": "𝕂", "𝒦": "𝒦", "Љ": "Љ", "<": "<", "Ĺ": "Ĺ", "Λ": "Λ", "⟪": "⟪", "ℒ": "ℒ", "↞": "↞", "Ľ": "Ľ", "Ļ": "Ļ", "Л": "Л", "⟨": "⟨", "←": "←", "⇤": "⇤", "⇆": "⇆", "⌈": "⌈", "⟦": "⟦", "⥡": "⥡", "⇃": "⇃", "⥙": "⥙", "⌊": "⌊", "↔": "↔", "⥎": "⥎", "⊣": "⊣", "↤": "↤", "⥚": "⥚", "⊲": "⊲", "⧏": "⧏", "⊴": "⊴", "⥑": "⥑", "⥠": "⥠", "↿": "↿", "⥘": "⥘", "↼": "↼", "⥒": "⥒", "⋚": "⋚", "≦": "≦", "≶": "≶", "⪡": "⪡", "⩽": "⩽", "≲": "≲", "𝔏": "𝔏", "⋘": "⋘", "⇚": "⇚", "Ŀ": "Ŀ", "⟵": "⟵", "⟷": "⟷", "⟶": "⟶", "𝕃": "𝕃", "↙": "↙", "↘": "↘", "↰": "↰", "Ł": "Ł", "≪": "≪", "⤅": "⤅", "М": "М", " ": " ", "ℳ": "ℳ", "𝔐": "𝔐", "∓": "∓", "𝕄": "𝕄", "Μ": "Μ", "Њ": "Њ", "Ń": "Ń", "Ň": "Ň", "Ņ": "Ņ", "Н": "Н", "​": "​", "\n": " ", "𝔑": "𝔑", "⁠": "⁠", " ": " ", "ℕ": "ℕ", "⫬": "⫬", "≢": "≢", "≭": "≭", "∦": "∦", "∉": "∉", "≠": "≠", "≂̸": "≂̸", "∄": "∄", "≯": "≯", "≱": "≱", "≧̸": "≧̸", "≫̸": "≫̸", "≹": "≹", "⩾̸": "⩾̸", "≵": "≵", "≎̸": "≎̸", "≏̸": "≏̸", "⋪": "⋪", "⧏̸": "⧏̸", "⋬": "⋬", "≮": "≮", "≰": "≰", "≸": "≸", "≪̸": "≪̸", "⩽̸": "⩽̸", "≴": "≴", "⪢̸": "⪢̸", "⪡̸": "⪡̸", "⊀": "⊀", "⪯̸": "⪯̸", "⋠": "⋠", "∌": "∌", "⋫": "⋫", "⧐̸": "⧐̸", "⋭": "⋭", "⊏̸": "⊏̸", "⋢": "⋢", "⊐̸": "⊐̸", "⋣": "⋣", "⊂⃒": "⊂⃒", "⊈": "⊈", "⊁": "⊁", "⪰̸": "⪰̸", "⋡": "⋡", "≿̸": "≿̸", "⊃⃒": "⊃⃒", "⊉": "⊉", "≁": "≁", "≄": "≄", "≇": "≇", "≉": "≉", "∤": "∤", "𝒩": "𝒩", "Ñ": "Ñ", "Ν": "Ν", "Œ": "Œ", "Ó": "Ó", "Ô": "Ô", "О": "О", "Ő": "Ő", "𝔒": "𝔒", "Ò": "Ò", "Ō": "Ō", "Ω": "Ω", "Ο": "Ο", "𝕆": "𝕆", "“": "“", "‘": "‘", "⩔": "⩔", "𝒪": "𝒪", "Ø": "Ø", "Õ": "Õ", "⨷": "⨷", "Ö": "Ö", "‾": "‾", "⏞": "⏞", "⎴": "⎴", "⏜": "⏜", "∂": "∂", "П": "П", "𝔓": "𝔓", "Φ": "Φ", "Π": "Π", "±": "±", "ℙ": "ℙ", "⪻": "⪻", "≺": "≺", "⪯": "⪯", "≼": "≼", "≾": "≾", "″": "″", "∏": "∏", "∝": "∝", "𝒫": "𝒫", "Ψ": "Ψ", '"': """, "𝔔": "𝔔", "ℚ": "ℚ", "𝒬": "𝒬", "⤐": "⤐", "®": "®", "Ŕ": "Ŕ", "⟫": "⟫", "↠": "↠", "⤖": "⤖", "Ř": "Ř", "Ŗ": "Ŗ", "Р": "Р", "ℜ": "ℜ", "∋": "∋", "⇋": "⇋", "⥯": "⥯", "Ρ": "Ρ", "⟩": "⟩", "→": "→", "⇥": "⇥", "⇄": "⇄", "⌉": "⌉", "⟧": "⟧", "⥝": "⥝", "⇂": "⇂", "⥕": "⥕", "⌋": "⌋", "⊢": "⊢", "↦": "↦", "⥛": "⥛", "⊳": "⊳", "⧐": "⧐", "⊵": "⊵", "⥏": "⥏", "⥜": "⥜", "↾": "↾", "⥔": "⥔", "⇀": "⇀", "⥓": "⥓", "ℝ": "ℝ", "⥰": "⥰", "⇛": "⇛", "ℛ": "ℛ", "↱": "↱", "⧴": "⧴", "Щ": "Щ", "Ш": "Ш", "Ь": "Ь", "Ś": "Ś", "⪼": "⪼", "Š": "Š", "Ş": "Ş", "Ŝ": "Ŝ", "С": "С", "𝔖": "𝔖", "↑": "↑", "Σ": "Σ", "∘": "∘", "𝕊": "𝕊", "√": "√", "□": "□", "⊓": "⊓", "⊏": "⊏", "⊑": "⊑", "⊐": "⊐", "⊒": "⊒", "⊔": "⊔", "𝒮": "𝒮", "⋆": "⋆", "⋐": "⋐", "⊆": "⊆", "≻": "≻", "⪰": "⪰", "≽": "≽", "≿": "≿", "∑": "∑", "⋑": "⋑", "⊃": "⊃", "⊇": "⊇", "Þ": "Þ", "™": "™", "Ћ": "Ћ", "Ц": "Ц", " ": " ", "Τ": "Τ", "Ť": "Ť", "Ţ": "Ţ", "Т": "Т", "𝔗": "𝔗", "∴": "∴", "Θ": "Θ", "  ": "  ", " ": " ", "∼": "∼", "≃": "≃", "≅": "≅", "≈": "≈", "𝕋": "𝕋", "⃛": "⃛", "𝒯": "𝒯", "Ŧ": "Ŧ", "Ú": "Ú", "↟": "↟", "⥉": "⥉", "Ў": "Ў", "Ŭ": "Ŭ", "Û": "Û", "У": "У", "Ű": "Ű", "𝔘": "𝔘", "Ù": "Ù", "Ū": "Ū", _: "_", "⏟": "⏟", "⎵": "⎵", "⏝": "⏝", "⋃": "⋃", "⊎": "⊎", "Ų": "Ų", "𝕌": "𝕌", "⤒": "⤒", "⇅": "⇅", "↕": "↕", "⥮": "⥮", "⊥": "⊥", "↥": "↥", "↖": "↖", "↗": "↗", "ϒ": "ϒ", "Υ": "Υ", "Ů": "Ů", "𝒰": "𝒰", "Ũ": "Ũ", "Ü": "Ü", "⊫": "⊫", "⫫": "⫫", "В": "В", "⊩": "⊩", "⫦": "⫦", "⋁": "⋁", "‖": "‖", "∣": "∣", "|": "|", "❘": "❘", "≀": "≀", " ": " ", "𝔙": "𝔙", "𝕍": "𝕍", "𝒱": "𝒱", "⊪": "⊪", "Ŵ": "Ŵ", "⋀": "⋀", "𝔚": "𝔚", "𝕎": "𝕎", "𝒲": "𝒲", "𝔛": "𝔛", "Ξ": "Ξ", "𝕏": "𝕏", "𝒳": "𝒳", "Я": "Я", "Ї": "Ї", "Ю": "Ю", "Ý": "Ý", "Ŷ": "Ŷ", "Ы": "Ы", "𝔜": "𝔜", "𝕐": "𝕐", "𝒴": "𝒴", "Ÿ": "Ÿ", "Ж": "Ж", "Ź": "Ź", "Ž": "Ž", "З": "З", "Ż": "Ż", "Ζ": "Ζ", "ℨ": "ℨ", "ℤ": "ℤ", "𝒵": "𝒵", "á": "á", "ă": "ă", "∾": "∾", "∾̳": "∾̳", "∿": "∿", "â": "â", "а": "а", "æ": "æ", "𝔞": "𝔞", "à": "à", "ℵ": "ℵ", "α": "α", "ā": "ā", "⨿": "⨿", "∧": "∧", "⩕": "⩕", "⩜": "⩜", "⩘": "⩘", "⩚": "⩚", "∠": "∠", "⦤": "⦤", "∡": "∡", "⦨": "⦨", "⦩": "⦩", "⦪": "⦪", "⦫": "⦫", "⦬": "⦬", "⦭": "⦭", "⦮": "⦮", "⦯": "⦯", "∟": "∟", "⊾": "⊾", "⦝": "⦝", "∢": "∢", "⍼": "⍼", "ą": "ą", "𝕒": "𝕒", "⩰": "⩰", "⩯": "⩯", "≊": "≊", "≋": "≋", "'": "'", "å": "å", "𝒶": "𝒶", "*": "*", "ã": "ã", "ä": "ä", "⨑": "⨑", "⫭": "⫭", "≌": "≌", "϶": "϶", "‵": "‵", "∽": "∽", "⋍": "⋍", "⊽": "⊽", "⌅": "⌅", "⎶": "⎶", "б": "б", "„": "„", "⦰": "⦰", "β": "β", "ℶ": "ℶ", "≬": "≬", "𝔟": "𝔟", "◯": "◯", "⨀": "⨀", "⨁": "⨁", "⨂": "⨂", "⨆": "⨆", "★": "★", "▽": "▽", "△": "△", "⨄": "⨄", "⤍": "⤍", "⧫": "⧫", "▴": "▴", "▾": "▾", "◂": "◂", "▸": "▸", "␣": "␣", "▒": "▒", "░": "░", "▓": "▓", "█": "█", "=⃥": "=⃥", "≡⃥": "≡⃥", "⌐": "⌐", "𝕓": "𝕓", "⋈": "⋈", "╗": "╗", "╔": "╔", "╖": "╖", "╓": "╓", "═": "═", "╦": "╦", "╩": "╩", "╤": "╤", "╧": "╧", "╝": "╝", "╚": "╚", "╜": "╜", "╙": "╙", "║": "║", "╬": "╬", "╣": "╣", "╠": "╠", "╫": "╫", "╢": "╢", "╟": "╟", "⧉": "⧉", "╕": "╕", "╒": "╒", "┐": "┐", "┌": "┌", "╥": "╥", "╨": "╨", "┬": "┬", "┴": "┴", "⊟": "⊟", "⊞": "⊞", "⊠": "⊠", "╛": "╛", "╘": "╘", "┘": "┘", "└": "└", "│": "│", "╪": "╪", "╡": "╡", "╞": "╞", "┼": "┼", "┤": "┤", "├": "├", "¦": "¦", "𝒷": "𝒷", "⁏": "⁏", "\\": "\", "⧅": "⧅", "⟈": "⟈", "•": "•", "⪮": "⪮", "ć": "ć", "∩": "∩", "⩄": "⩄", "⩉": "⩉", "⩋": "⩋", "⩇": "⩇", "⩀": "⩀", "∩︀": "∩︀", "⁁": "⁁", "⩍": "⩍", "č": "č", "ç": "ç", "ĉ": "ĉ", "⩌": "⩌", "⩐": "⩐", "ċ": "ċ", "⦲": "⦲", "¢": "¢", "𝔠": "𝔠", "ч": "ч", "✓": "✓", "χ": "χ", "○": "○", "⧃": "⧃", "ˆ": "ˆ", "≗": "≗", "↺": "↺", "↻": "↻", "Ⓢ": "Ⓢ", "⊛": "⊛", "⊚": "⊚", "⊝": "⊝", "⨐": "⨐", "⫯": "⫯", "⧂": "⧂", "♣": "♣", ":": ":", ",": ",", "@": "@", "∁": "∁", "⩭": "⩭", "𝕔": "𝕔", "℗": "℗", "↵": "↵", "✗": "✗", "𝒸": "𝒸", "⫏": "⫏", "⫑": "⫑", "⫐": "⫐", "⫒": "⫒", "⋯": "⋯", "⤸": "⤸", "⤵": "⤵", "⋞": "⋞", "⋟": "⋟", "↶": "↶", "⤽": "⤽", "∪": "∪", "⩈": "⩈", "⩆": "⩆", "⩊": "⩊", "⊍": "⊍", "⩅": "⩅", "∪︀": "∪︀", "↷": "↷", "⤼": "⤼", "⋎": "⋎", "⋏": "⋏", "¤": "¤", "∱": "∱", "⌭": "⌭", "⥥": "⥥", "†": "†", "ℸ": "ℸ", "‐": "‐", "⤏": "⤏", "ď": "ď", "д": "д", "⇊": "⇊", "⩷": "⩷", "°": "°", "δ": "δ", "⦱": "⦱", "⥿": "⥿", "𝔡": "𝔡", "♦": "♦", "ϝ": "ϝ", "⋲": "⋲", "÷": "÷", "⋇": "⋇", "ђ": "ђ", "⌞": "⌞", "⌍": "⌍", $: "$", "𝕕": "𝕕", "≑": "≑", "∸": "∸", "∔": "∔", "⊡": "⊡", "⌟": "⌟", "⌌": "⌌", "𝒹": "𝒹", "ѕ": "ѕ", "⧶": "⧶", "đ": "đ", "⋱": "⋱", "▿": "▿", "⦦": "⦦", "џ": "џ", "⟿": "⟿", "é": "é", "⩮": "⩮", "ě": "ě", "≖": "≖", "ê": "ê", "≕": "≕", "э": "э", "ė": "ė", "≒": "≒", "𝔢": "𝔢", "⪚": "⪚", "è": "è", "⪖": "⪖", "⪘": "⪘", "⪙": "⪙", "⏧": "⏧", "ℓ": "ℓ", "⪕": "⪕", "⪗": "⪗", "ē": "ē", "∅": "∅", " ": " ", " ": " ", " ": " ", "ŋ": "ŋ", " ": " ", "ę": "ę", "𝕖": "𝕖", "⋕": "⋕", "⧣": "⧣", "⩱": "⩱", "ε": "ε", "ϵ": "ϵ", "=": "=", "≟": "≟", "⩸": "⩸", "⧥": "⧥", "≓": "≓", "⥱": "⥱", "ℯ": "ℯ", "η": "η", "ð": "ð", "ë": "ë", "€": "€", "!": "!", "ф": "ф", "♀": "♀", "ffi": "ffi", "ff": "ff", "ffl": "ffl", "𝔣": "𝔣", "fi": "fi", fj: "fj", "♭": "♭", "fl": "fl", "▱": "▱", "ƒ": "ƒ", "𝕗": "𝕗", "⋔": "⋔", "⫙": "⫙", "⨍": "⨍", "½": "½", "⅓": "⅓", "¼": "¼", "⅕": "⅕", "⅙": "⅙", "⅛": "⅛", "⅔": "⅔", "⅖": "⅖", "¾": "¾", "⅗": "⅗", "⅜": "⅜", "⅘": "⅘", "⅚": "⅚", "⅝": "⅝", "⅞": "⅞", "⁄": "⁄", "⌢": "⌢", "𝒻": "𝒻", "⪌": "⪌", "ǵ": "ǵ", "γ": "γ", "⪆": "⪆", "ğ": "ğ", "ĝ": "ĝ", "г": "г", "ġ": "ġ", "⪩": "⪩", "⪀": "⪀", "⪂": "⪂", "⪄": "⪄", "⋛︀": "⋛︀", "⪔": "⪔", "𝔤": "𝔤", "ℷ": "ℷ", "ѓ": "ѓ", "⪒": "⪒", "⪥": "⪥", "⪤": "⪤", "≩": "≩", "⪊": "⪊", "⪈": "⪈", "⋧": "⋧", "𝕘": "𝕘", "ℊ": "ℊ", "⪎": "⪎", "⪐": "⪐", "⪧": "⪧", "⩺": "⩺", "⋗": "⋗", "⦕": "⦕", "⩼": "⩼", "⥸": "⥸", "≩︀": "≩︀", "ъ": "ъ", "⥈": "⥈", "↭": "↭", "ℏ": "ℏ", "ĥ": "ĥ", "♥": "♥", "…": "…", "⊹": "⊹", "𝔥": "𝔥", "⤥": "⤥", "⤦": "⤦", "⇿": "⇿", "∻": "∻", "↩": "↩", "↪": "↪", "𝕙": "𝕙", "―": "―", "𝒽": "𝒽", "ħ": "ħ", "⁃": "⁃", "í": "í", "î": "î", "и": "и", "е": "е", "¡": "¡", "𝔦": "𝔦", "ì": "ì", "⨌": "⨌", "∭": "∭", "⧜": "⧜", "℩": "℩", "ij": "ij", "ī": "ī", "ı": "ı", "⊷": "⊷", "Ƶ": "Ƶ", "℅": "℅", "∞": "∞", "⧝": "⧝", "⊺": "⊺", "⨗": "⨗", "⨼": "⨼", "ё": "ё", "į": "į", "𝕚": "𝕚", "ι": "ι", "¿": "¿", "𝒾": "𝒾", "⋹": "⋹", "⋵": "⋵", "⋴": "⋴", "⋳": "⋳", "ĩ": "ĩ", "і": "і", "ï": "ï", "ĵ": "ĵ", "й": "й", "𝔧": "𝔧", "ȷ": "ȷ", "𝕛": "𝕛", "𝒿": "𝒿", "ј": "ј", "є": "є", "κ": "κ", "ϰ": "ϰ", "ķ": "ķ", "к": "к", "𝔨": "𝔨", "ĸ": "ĸ", "х": "х", "ќ": "ќ", "𝕜": "𝕜", "𝓀": "𝓀", "⤛": "⤛", "⤎": "⤎", "⪋": "⪋", "⥢": "⥢", "ĺ": "ĺ", "⦴": "⦴", "λ": "λ", "⦑": "⦑", "⪅": "⪅", "«": "«", "⤟": "⤟", "⤝": "⤝", "↫": "↫", "⤹": "⤹", "⥳": "⥳", "↢": "↢", "⪫": "⪫", "⤙": "⤙", "⪭": "⪭", "⪭︀": "⪭︀", "⤌": "⤌", "❲": "❲", "{": "{", "[": "[", "⦋": "⦋", "⦏": "⦏", "⦍": "⦍", "ľ": "ľ", "ļ": "ļ", "л": "л", "⤶": "⤶", "⥧": "⥧", "⥋": "⥋", "↲": "↲", "≤": "≤", "⇇": "⇇", "⋋": "⋋", "⪨": "⪨", "⩿": "⩿", "⪁": "⪁", "⪃": "⪃", "⋚︀": "⋚︀", "⪓": "⪓", "⋖": "⋖", "⥼": "⥼", "𝔩": "𝔩", "⪑": "⪑", "⥪": "⥪", "▄": "▄", "љ": "љ", "⥫": "⥫", "◺": "◺", "ŀ": "ŀ", "⎰": "⎰", "≨": "≨", "⪉": "⪉", "⪇": "⪇", "⋦": "⋦", "⟬": "⟬", "⇽": "⇽", "⟼": "⟼", "↬": "↬", "⦅": "⦅", "𝕝": "𝕝", "⨭": "⨭", "⨴": "⨴", "∗": "∗", "◊": "◊", "(": "(", "⦓": "⦓", "⥭": "⥭", "‎": "‎", "⊿": "⊿", "‹": "‹", "𝓁": "𝓁", "⪍": "⪍", "⪏": "⪏", "‚": "‚", "ł": "ł", "⪦": "⪦", "⩹": "⩹", "⋉": "⋉", "⥶": "⥶", "⩻": "⩻", "⦖": "⦖", "◃": "◃", "⥊": "⥊", "⥦": "⥦", "≨︀": "≨︀", "∺": "∺", "¯": "¯", "♂": "♂", "✠": "✠", "▮": "▮", "⨩": "⨩", "м": "м", "—": "—", "𝔪": "𝔪", "℧": "℧", "µ": "µ", "⫰": "⫰", "−": "−", "⨪": "⨪", "⫛": "⫛", "⊧": "⊧", "𝕞": "𝕞", "𝓂": "𝓂", "μ": "μ", "⊸": "⊸", "⋙̸": "⋙̸", "≫⃒": "≫⃒", "⇍": "⇍", "⇎": "⇎", "⋘̸": "⋘̸", "≪⃒": "≪⃒", "⇏": "⇏", "⊯": "⊯", "⊮": "⊮", "ń": "ń", "∠⃒": "∠⃒", "⩰̸": "⩰̸", "≋̸": "≋̸", "ʼn": "ʼn", "♮": "♮", "⩃": "⩃", "ň": "ň", "ņ": "ņ", "⩭̸": "⩭̸", "⩂": "⩂", "н": "н", "–": "–", "⇗": "⇗", "⤤": "⤤", "≐̸": "≐̸", "⤨": "⤨", "𝔫": "𝔫", "↮": "↮", "⫲": "⫲", "⋼": "⋼", "⋺": "⋺", "њ": "њ", "≦̸": "≦̸", "↚": "↚", "‥": "‥", "𝕟": "𝕟", "¬": "¬", "⋹̸": "⋹̸", "⋵̸": "⋵̸", "⋷": "⋷", "⋶": "⋶", "⋾": "⋾", "⋽": "⋽", "⫽⃥": "⫽⃥", "∂̸": "∂̸", "⨔": "⨔", "↛": "↛", "⤳̸": "⤳̸", "↝̸": "↝̸", "𝓃": "𝓃", "⊄": "⊄", "⫅̸": "⫅̸", "⊅": "⊅", "⫆̸": "⫆̸", "ñ": "ñ", "ν": "ν", "#": "#", "№": "№", " ": " ", "⊭": "⊭", "⤄": "⤄", "≍⃒": "≍⃒", "⊬": "⊬", "≥⃒": "≥⃒", ">⃒": ">⃒", "⧞": "⧞", "⤂": "⤂", "≤⃒": "≤⃒", "<⃒": "<⃒", "⊴⃒": "⊴⃒", "⤃": "⤃", "⊵⃒": "⊵⃒", "∼⃒": "∼⃒", "⇖": "⇖", "⤣": "⤣", "⤧": "⤧", "ó": "ó", "ô": "ô", "о": "о", "ő": "ő", "⨸": "⨸", "⦼": "⦼", "œ": "œ", "⦿": "⦿", "𝔬": "𝔬", "˛": "˛", "ò": "ò", "⧁": "⧁", "⦵": "⦵", "⦾": "⦾", "⦻": "⦻", "⧀": "⧀", "ō": "ō", "ω": "ω", "ο": "ο", "⦶": "⦶", "𝕠": "𝕠", "⦷": "⦷", "⦹": "⦹", "∨": "∨", "⩝": "⩝", "ℴ": "ℴ", "ª": "ª", "º": "º", "⊶": "⊶", "⩖": "⩖", "⩗": "⩗", "⩛": "⩛", "ø": "ø", "⊘": "⊘", "õ": "õ", "⨶": "⨶", "ö": "ö", "⌽": "⌽", "¶": "¶", "⫳": "⫳", "⫽": "⫽", "п": "п", "%": "%", ".": ".", "‰": "‰", "‱": "‱", "𝔭": "𝔭", "φ": "φ", "ϕ": "ϕ", "☎": "☎", "π": "π", "ϖ": "ϖ", "ℎ": "ℎ", "+": "+", "⨣": "⨣", "⨢": "⨢", "⨥": "⨥", "⩲": "⩲", "⨦": "⨦", "⨧": "⨧", "⨕": "⨕", "𝕡": "𝕡", "£": "£", "⪳": "⪳", "⪷": "⪷", "⪹": "⪹", "⪵": "⪵", "⋨": "⋨", "′": "′", "⌮": "⌮", "⌒": "⌒", "⌓": "⌓", "⊰": "⊰", "𝓅": "𝓅", "ψ": "ψ", " ": " ", "𝔮": "𝔮", "𝕢": "𝕢", "⁗": "⁗", "𝓆": "𝓆", "⨖": "⨖", "?": "?", "⤜": "⤜", "⥤": "⥤", "∽̱": "∽̱", "ŕ": "ŕ", "⦳": "⦳", "⦒": "⦒", "⦥": "⦥", "»": "»", "⥵": "⥵", "⤠": "⤠", "⤳": "⤳", "⤞": "⤞", "⥅": "⥅", "⥴": "⥴", "↣": "↣", "↝": "↝", "⤚": "⤚", "∶": "∶", "❳": "❳", "}": "}", "]": "]", "⦌": "⦌", "⦎": "⦎", "⦐": "⦐", "ř": "ř", "ŗ": "ŗ", "р": "р", "⤷": "⤷", "⥩": "⥩", "↳": "↳", "▭": "▭", "⥽": "⥽", "𝔯": "𝔯", "⥬": "⥬", "ρ": "ρ", "ϱ": "ϱ", "⇉": "⇉", "⋌": "⋌", "˚": "˚", "‏": "‏", "⎱": "⎱", "⫮": "⫮", "⟭": "⟭", "⇾": "⇾", "⦆": "⦆", "𝕣": "𝕣", "⨮": "⨮", "⨵": "⨵", ")": ")", "⦔": "⦔", "⨒": "⨒", "›": "›", "𝓇": "𝓇", "⋊": "⋊", "▹": "▹", "⧎": "⧎", "⥨": "⥨", "℞": "℞", "ś": "ś", "⪴": "⪴", "⪸": "⪸", "š": "š", "ş": "ş", "ŝ": "ŝ", "⪶": "⪶", "⪺": "⪺", "⋩": "⋩", "⨓": "⨓", "с": "с", "⋅": "⋅", "⩦": "⩦", "⇘": "⇘", "§": "§", ";": ";", "⤩": "⤩", "✶": "✶", "𝔰": "𝔰", "♯": "♯", "щ": "щ", "ш": "ш", "­": "­", "σ": "σ", "ς": "ς", "⩪": "⩪", "⪞": "⪞", "⪠": "⪠", "⪝": "⪝", "⪟": "⪟", "≆": "≆", "⨤": "⨤", "⥲": "⥲", "⨳": "⨳", "⧤": "⧤", "⌣": "⌣", "⪪": "⪪", "⪬": "⪬", "⪬︀": "⪬︀", "ь": "ь", "/": "/", "⧄": "⧄", "⌿": "⌿", "𝕤": "𝕤", "♠": "♠", "⊓︀": "⊓︀", "⊔︀": "⊔︀", "𝓈": "𝓈", "☆": "☆", "⊂": "⊂", "⫅": "⫅", "⪽": "⪽", "⫃": "⫃", "⫁": "⫁", "⫋": "⫋", "⊊": "⊊", "⪿": "⪿", "⥹": "⥹", "⫇": "⫇", "⫕": "⫕", "⫓": "⫓", "♪": "♪", "¹": "¹", "²": "²", "³": "³", "⫆": "⫆", "⪾": "⪾", "⫘": "⫘", "⫄": "⫄", "⟉": "⟉", "⫗": "⫗", "⥻": "⥻", "⫂": "⫂", "⫌": "⫌", "⊋": "⊋", "⫀": "⫀", "⫈": "⫈", "⫔": "⫔", "⫖": "⫖", "⇙": "⇙", "⤪": "⤪", "ß": "ß", "⌖": "⌖", "τ": "τ", "ť": "ť", "ţ": "ţ", "т": "т", "⌕": "⌕", "𝔱": "𝔱", "θ": "θ", "ϑ": "ϑ", "þ": "þ", "×": "×", "⨱": "⨱", "⨰": "⨰", "⌶": "⌶", "⫱": "⫱", "𝕥": "𝕥", "⫚": "⫚", "‴": "‴", "▵": "▵", "≜": "≜", "◬": "◬", "⨺": "⨺", "⨹": "⨹", "⧍": "⧍", "⨻": "⨻", "⏢": "⏢", "𝓉": "𝓉", "ц": "ц", "ћ": "ћ", "ŧ": "ŧ", "⥣": "⥣", "ú": "ú", "ў": "ў", "ŭ": "ŭ", "û": "û", "у": "у", "ű": "ű", "⥾": "⥾", "𝔲": "𝔲", "ù": "ù", "▀": "▀", "⌜": "⌜", "⌏": "⌏", "◸": "◸", "ū": "ū", "ų": "ų", "𝕦": "𝕦", "υ": "υ", "⇈": "⇈", "⌝": "⌝", "⌎": "⌎", "ů": "ů", "◹": "◹", "𝓊": "𝓊", "⋰": "⋰", "ũ": "ũ", "ü": "ü", "⦧": "⦧", "⫨": "⫨", "⫩": "⫩", "⦜": "⦜", "⊊︀": "⊊︀", "⫋︀": "⫋︀", "⊋︀": "⊋︀", "⫌︀": "⫌︀", "в": "в", "⊻": "⊻", "≚": "≚", "⋮": "⋮", "𝔳": "𝔳", "𝕧": "𝕧", "𝓋": "𝓋", "⦚": "⦚", "ŵ": "ŵ", "⩟": "⩟", "≙": "≙", "℘": "℘", "𝔴": "𝔴", "𝕨": "𝕨", "𝓌": "𝓌", "𝔵": "𝔵", "ξ": "ξ", "⋻": "⋻", "𝕩": "𝕩", "𝓍": "𝓍", "ý": "ý", "я": "я", "ŷ": "ŷ", "ы": "ы", "¥": "¥", "𝔶": "𝔶", "ї": "ї", "𝕪": "𝕪", "𝓎": "𝓎", "ю": "ю", "ÿ": "ÿ", "ź": "ź", "ž": "ž", "з": "з", "ż": "ż", "ζ": "ζ", "𝔷": "𝔷", "ж": "ж", "⇝": "⇝", "𝕫": "𝕫", "𝓏": "𝓏", "‍": "‍", "‌": "‌" } } }; - } -}); - -// node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/numeric-unicode-map.js -var require_numeric_unicode_map = __commonJS({ - "node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/numeric-unicode-map.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.numericUnicodeMap = { 0: 65533, 128: 8364, 130: 8218, 131: 402, 132: 8222, 133: 8230, 134: 8224, 135: 8225, 136: 710, 137: 8240, 138: 352, 139: 8249, 140: 338, 142: 381, 145: 8216, 146: 8217, 147: 8220, 148: 8221, 149: 8226, 150: 8211, 151: 8212, 152: 732, 153: 8482, 154: 353, 155: 8250, 156: 339, 158: 382, 159: 376 }; - } -}); - -// node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/surrogate-pairs.js -var require_surrogate_pairs = __commonJS({ - "node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/surrogate-pairs.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.fromCodePoint = String.fromCodePoint || function(astralCodePoint) { - return String.fromCharCode(Math.floor((astralCodePoint - 65536) / 1024) + 55296, (astralCodePoint - 65536) % 1024 + 56320); - }; - exports.getCodePoint = String.prototype.codePointAt ? function(input, position) { - return input.codePointAt(position); - } : function(input, position) { - return (input.charCodeAt(position) - 55296) * 1024 + input.charCodeAt(position + 1) - 56320 + 65536; - }; - exports.highSurrogateFrom = 55296; - exports.highSurrogateTo = 56319; - } -}); - -// node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/index.js -var require_lib = __commonJS({ - "node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/index.js"(exports) { - "use strict"; - var __assign = exports && exports.__assign || function() { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) - if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); - }; - Object.defineProperty(exports, "__esModule", { value: true }); - var named_references_1 = require_named_references(); - var numeric_unicode_map_1 = require_numeric_unicode_map(); - var surrogate_pairs_1 = require_surrogate_pairs(); - var allNamedReferences = __assign(__assign({}, named_references_1.namedReferences), { all: named_references_1.namedReferences.html5 }); - var encodeRegExps = { - specialChars: /[<>'"&]/g, - nonAscii: /(?:[<>'"&\u0080-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g, - nonAsciiPrintable: /(?:[<>'"&\x01-\x08\x11-\x15\x17-\x1F\x7f-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g, - extensive: /(?:[\x01-\x0c\x0e-\x1f\x21-\x2c\x2e-\x2f\x3a-\x40\x5b-\x60\x7b-\x7d\x7f-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g - }; - var defaultEncodeOptions = { - mode: "specialChars", - level: "all", - numeric: "decimal" - }; - function encode(text, _a) { - var _b = _a === void 0 ? defaultEncodeOptions : _a, _c = _b.mode, mode = _c === void 0 ? "specialChars" : _c, _d = _b.numeric, numeric = _d === void 0 ? "decimal" : _d, _e = _b.level, level = _e === void 0 ? "all" : _e; - if (!text) { - return ""; - } - var encodeRegExp = encodeRegExps[mode]; - var references = allNamedReferences[level].characters; - var isHex = numeric === "hexadecimal"; - encodeRegExp.lastIndex = 0; - var _b = encodeRegExp.exec(text); - var _c; - if (_b) { - _c = ""; - var _d = 0; - do { - if (_d !== _b.index) { - _c += text.substring(_d, _b.index); - } - var _e = _b[0]; - var result_1 = references[_e]; - if (!result_1) { - var code_1 = _e.length > 1 ? surrogate_pairs_1.getCodePoint(_e, 0) : _e.charCodeAt(0); - result_1 = (isHex ? "&#x" + code_1.toString(16) : "&#" + code_1) + ";"; - } - _c += result_1; - _d = _b.index + _e.length; - } while (_b = encodeRegExp.exec(text)); - if (_d !== text.length) { - _c += text.substring(_d); - } - } else { - _c = text; - } - return _c; - } - exports.encode = encode; - var defaultDecodeOptions = { - scope: "body", - level: "all" - }; - var strict = /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);/g; - var attribute = /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+)[;=]?/g; - var baseDecodeRegExps = { - xml: { - strict, - attribute, - body: named_references_1.bodyRegExps.xml - }, - html4: { - strict, - attribute, - body: named_references_1.bodyRegExps.html4 - }, - html5: { - strict, - attribute, - body: named_references_1.bodyRegExps.html5 - } - }; - var decodeRegExps = __assign(__assign({}, baseDecodeRegExps), { all: baseDecodeRegExps.html5 }); - var fromCharCode = String.fromCharCode; - var outOfBoundsChar = fromCharCode(65533); - var defaultDecodeEntityOptions = { - level: "all" - }; - function decodeEntity(entity, _a) { - var _b = (_a === void 0 ? defaultDecodeEntityOptions : _a).level, level = _b === void 0 ? "all" : _b; - if (!entity) { - return ""; - } - var _b = entity; - var decodeEntityLastChar_1 = entity[entity.length - 1]; - if (false) { - _b = entity; - } else if (false) { - _b = entity; - } else { - var decodeResultByReference_1 = allNamedReferences[level].entities[entity]; - if (decodeResultByReference_1) { - _b = decodeResultByReference_1; - } else if (entity[0] === "&" && entity[1] === "#") { - var decodeSecondChar_1 = entity[2]; - var decodeCode_1 = decodeSecondChar_1 == "x" || decodeSecondChar_1 == "X" ? parseInt(entity.substr(3), 16) : parseInt(entity.substr(2)); - _b = decodeCode_1 >= 1114111 ? outOfBoundsChar : decodeCode_1 > 65535 ? surrogate_pairs_1.fromCodePoint(decodeCode_1) : fromCharCode(numeric_unicode_map_1.numericUnicodeMap[decodeCode_1] || decodeCode_1); - } - } - return _b; - } - exports.decodeEntity = decodeEntity; - function decode2(text, _a) { - var decodeSecondChar_1 = _a === void 0 ? defaultDecodeOptions : _a, decodeCode_1 = decodeSecondChar_1.level, level = decodeCode_1 === void 0 ? "all" : decodeCode_1, _b = decodeSecondChar_1.scope, scope = _b === void 0 ? level === "xml" ? "strict" : "body" : _b; - if (!text) { - return ""; - } - var decodeRegExp = decodeRegExps[level][scope]; - var references = allNamedReferences[level].entities; - var isAttribute = scope === "attribute"; - var isStrict = scope === "strict"; - decodeRegExp.lastIndex = 0; - var replaceMatch_1 = decodeRegExp.exec(text); - var replaceResult_1; - if (replaceMatch_1) { - replaceResult_1 = ""; - var replaceLastIndex_1 = 0; - do { - if (replaceLastIndex_1 !== replaceMatch_1.index) { - replaceResult_1 += text.substring(replaceLastIndex_1, replaceMatch_1.index); - } - var replaceInput_1 = replaceMatch_1[0]; - var decodeResult_1 = replaceInput_1; - var decodeEntityLastChar_2 = replaceInput_1[replaceInput_1.length - 1]; - if (isAttribute && decodeEntityLastChar_2 === "=") { - decodeResult_1 = replaceInput_1; - } else if (isStrict && decodeEntityLastChar_2 !== ";") { - decodeResult_1 = replaceInput_1; - } else { - var decodeResultByReference_2 = references[replaceInput_1]; - if (decodeResultByReference_2) { - decodeResult_1 = decodeResultByReference_2; - } else if (replaceInput_1[0] === "&" && replaceInput_1[1] === "#") { - var decodeSecondChar_2 = replaceInput_1[2]; - var decodeCode_2 = decodeSecondChar_2 == "x" || decodeSecondChar_2 == "X" ? parseInt(replaceInput_1.substr(3), 16) : parseInt(replaceInput_1.substr(2)); - decodeResult_1 = decodeCode_2 >= 1114111 ? outOfBoundsChar : decodeCode_2 > 65535 ? surrogate_pairs_1.fromCodePoint(decodeCode_2) : fromCharCode(numeric_unicode_map_1.numericUnicodeMap[decodeCode_2] || decodeCode_2); - } - } - replaceResult_1 += decodeResult_1; - replaceLastIndex_1 = replaceMatch_1.index + replaceInput_1.length; - } while (replaceMatch_1 = decodeRegExp.exec(text)); - if (replaceLastIndex_1 !== text.length) { - replaceResult_1 += text.substring(replaceLastIndex_1); - } - } else { - replaceResult_1 = text; - } - return replaceResult_1; - } - exports.decode = decode2; - } -}); - // node_modules/.pnpm/fast-xml-parser@4.0.9/node_modules/fast-xml-parser/src/util.js var require_util = __commonJS({ "node_modules/.pnpm/fast-xml-parser@4.0.9/node_modules/fast-xml-parser/src/util.js"(exports) { @@ -12901,11 +12692,11 @@ var require_validator2 = __commonJS({ if (attrStr[attrStr.length - 1] === "/") { const attrStrStart = i - attrStr.length; attrStr = attrStr.substring(0, attrStr.length - 1); - const isValid = validateAttributeString(attrStr, options); - if (isValid === true) { + const isValid2 = validateAttributeString(attrStr, options); + if (isValid2 === true) { tagFound = true; } else { - return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line)); + return getErrorObject(isValid2.err.code, isValid2.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid2.err.line)); } } else if (closingTag) { if (!result.tagClosed) { @@ -12923,9 +12714,9 @@ var require_validator2 = __commonJS({ } } } else { - const isValid = validateAttributeString(attrStr, options); - if (isValid !== true) { - return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line)); + const isValid2 = validateAttributeString(attrStr, options); + if (isValid2 !== true) { + return getErrorObject(isValid2.err.code, isValid2.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid2.err.line)); } if (reachedRoot === true) { return getErrorObject("InvalidXml", "Multiple possible root nodes found.", getLineNumberForPosition(xmlData, i)); @@ -14294,9 +14085,9 @@ var require_json2xml = __commonJS({ function indentate(level) { return this.options.indentBy.repeat(level); } - function isAttribute(name2) { - if (name2.startsWith(this.options.attributeNamePrefix)) { - return name2.substr(this.attrPrefixLen); + function isAttribute(name) { + if (name.startsWith(this.options.attributeNamePrefix)) { + return name.substr(this.attrPrefixLen); } else { return false; } @@ -14320,93 +14111,235 @@ var require_fxp = __commonJS({ } }); -// src/main.js -var main_exports = {}; -__export(main_exports, { - getRequestOptions: () => getRequestOptions, - onComplete: () => onComplete, - onError: () => onError, - onSuccess: () => onSuccess, - read: () => read, - resetEvents: () => resetEvents, - setRequestOptions: () => setRequestOptions +// node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/named-references.js +var require_named_references = __commonJS({ + "node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/named-references.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.bodyRegExps = { xml: /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g, html4: /&(?:nbsp|iexcl|cent|pound|curren|yen|brvbar|sect|uml|copy|ordf|laquo|not|shy|reg|macr|deg|plusmn|sup2|sup3|acute|micro|para|middot|cedil|sup1|ordm|raquo|frac14|frac12|frac34|iquest|Agrave|Aacute|Acirc|Atilde|Auml|Aring|AElig|Ccedil|Egrave|Eacute|Ecirc|Euml|Igrave|Iacute|Icirc|Iuml|ETH|Ntilde|Ograve|Oacute|Ocirc|Otilde|Ouml|times|Oslash|Ugrave|Uacute|Ucirc|Uuml|Yacute|THORN|szlig|agrave|aacute|acirc|atilde|auml|aring|aelig|ccedil|egrave|eacute|ecirc|euml|igrave|iacute|icirc|iuml|eth|ntilde|ograve|oacute|ocirc|otilde|ouml|divide|oslash|ugrave|uacute|ucirc|uuml|yacute|thorn|yuml|quot|amp|lt|gt|#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g, html5: /&(?:AElig|AMP|Aacute|Acirc|Agrave|Aring|Atilde|Auml|COPY|Ccedil|ETH|Eacute|Ecirc|Egrave|Euml|GT|Iacute|Icirc|Igrave|Iuml|LT|Ntilde|Oacute|Ocirc|Ograve|Oslash|Otilde|Ouml|QUOT|REG|THORN|Uacute|Ucirc|Ugrave|Uuml|Yacute|aacute|acirc|acute|aelig|agrave|amp|aring|atilde|auml|brvbar|ccedil|cedil|cent|copy|curren|deg|divide|eacute|ecirc|egrave|eth|euml|frac12|frac14|frac34|gt|iacute|icirc|iexcl|igrave|iquest|iuml|laquo|lt|macr|micro|middot|nbsp|not|ntilde|oacute|ocirc|ograve|ordf|ordm|oslash|otilde|ouml|para|plusmn|pound|quot|raquo|reg|sect|shy|sup1|sup2|sup3|szlig|thorn|times|uacute|ucirc|ugrave|uml|uuml|yacute|yen|yuml|#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g }; + exports.namedReferences = { xml: { entities: { "<": "<", ">": ">", """: '"', "'": "'", "&": "&" }, characters: { "<": "<", ">": ">", '"': """, "'": "'", "&": "&" } }, html4: { entities: { "'": "'", " ": " ", " ": " ", "¡": "¡", "¡": "¡", "¢": "¢", "¢": "¢", "£": "£", "£": "£", "¤": "¤", "¤": "¤", "¥": "¥", "¥": "¥", "¦": "¦", "¦": "¦", "§": "§", "§": "§", "¨": "¨", "¨": "¨", "©": "©", "©": "©", "ª": "ª", "ª": "ª", "«": "«", "«": "«", "¬": "¬", "¬": "¬", "­": "­", "­": "­", "®": "®", "®": "®", "¯": "¯", "¯": "¯", "°": "°", "°": "°", "±": "±", "±": "±", "²": "²", "²": "²", "³": "³", "³": "³", "´": "´", "´": "´", "µ": "µ", "µ": "µ", "¶": "¶", "¶": "¶", "·": "·", "·": "·", "¸": "¸", "¸": "¸", "¹": "¹", "¹": "¹", "º": "º", "º": "º", "»": "»", "»": "»", "¼": "¼", "¼": "¼", "½": "½", "½": "½", "¾": "¾", "¾": "¾", "¿": "¿", "¿": "¿", "À": "À", "À": "À", "Á": "Á", "Á": "Á", "Â": "Â", "Â": "Â", "Ã": "Ã", "Ã": "Ã", "Ä": "Ä", "Ä": "Ä", "Å": "Å", "Å": "Å", "Æ": "Æ", "Æ": "Æ", "Ç": "Ç", "Ç": "Ç", "È": "È", "È": "È", "É": "É", "É": "É", "Ê": "Ê", "Ê": "Ê", "Ë": "Ë", "Ë": "Ë", "Ì": "Ì", "Ì": "Ì", "Í": "Í", "Í": "Í", "Î": "Î", "Î": "Î", "Ï": "Ï", "Ï": "Ï", "Ð": "Ð", "Ð": "Ð", "Ñ": "Ñ", "Ñ": "Ñ", "Ò": "Ò", "Ò": "Ò", "Ó": "Ó", "Ó": "Ó", "Ô": "Ô", "Ô": "Ô", "Õ": "Õ", "Õ": "Õ", "Ö": "Ö", "Ö": "Ö", "×": "×", "×": "×", "Ø": "Ø", "Ø": "Ø", "Ù": "Ù", "Ù": "Ù", "Ú": "Ú", "Ú": "Ú", "Û": "Û", "Û": "Û", "Ü": "Ü", "Ü": "Ü", "Ý": "Ý", "Ý": "Ý", "Þ": "Þ", "Þ": "Þ", "ß": "ß", "ß": "ß", "à": "à", "à": "à", "á": "á", "á": "á", "â": "â", "â": "â", "ã": "ã", "ã": "ã", "ä": "ä", "ä": "ä", "å": "å", "å": "å", "æ": "æ", "æ": "æ", "ç": "ç", "ç": "ç", "è": "è", "è": "è", "é": "é", "é": "é", "ê": "ê", "ê": "ê", "ë": "ë", "ë": "ë", "ì": "ì", "ì": "ì", "í": "í", "í": "í", "î": "î", "î": "î", "ï": "ï", "ï": "ï", "ð": "ð", "ð": "ð", "ñ": "ñ", "ñ": "ñ", "ò": "ò", "ò": "ò", "ó": "ó", "ó": "ó", "ô": "ô", "ô": "ô", "õ": "õ", "õ": "õ", "ö": "ö", "ö": "ö", "÷": "÷", "÷": "÷", "ø": "ø", "ø": "ø", "ù": "ù", "ù": "ù", "ú": "ú", "ú": "ú", "û": "û", "û": "û", "ü": "ü", "ü": "ü", "ý": "ý", "ý": "ý", "þ": "þ", "þ": "þ", "ÿ": "ÿ", "ÿ": "ÿ", """: '"', """: '"', "&": "&", "&": "&", "<": "<", "<": "<", ">": ">", ">": ">", "Œ": "Œ", "œ": "œ", "Š": "Š", "š": "š", "Ÿ": "Ÿ", "ˆ": "ˆ", "˜": "˜", " ": " ", " ": " ", " ": " ", "‌": "‌", "‍": "‍", "‎": "‎", "‏": "‏", "–": "–", "—": "—", "‘": "‘", "’": "’", "‚": "‚", "“": "“", "”": "”", "„": "„", "†": "†", "‡": "‡", "‰": "‰", "‹": "‹", "›": "›", "€": "€", "ƒ": "ƒ", "Α": "Α", "Β": "Β", "Γ": "Γ", "Δ": "Δ", "Ε": "Ε", "Ζ": "Ζ", "Η": "Η", "Θ": "Θ", "Ι": "Ι", "Κ": "Κ", "Λ": "Λ", "Μ": "Μ", "Ν": "Ν", "Ξ": "Ξ", "Ο": "Ο", "Π": "Π", "Ρ": "Ρ", "Σ": "Σ", "Τ": "Τ", "Υ": "Υ", "Φ": "Φ", "Χ": "Χ", "Ψ": "Ψ", "Ω": "Ω", "α": "α", "β": "β", "γ": "γ", "δ": "δ", "ε": "ε", "ζ": "ζ", "η": "η", "θ": "θ", "ι": "ι", "κ": "κ", "λ": "λ", "μ": "μ", "ν": "ν", "ξ": "ξ", "ο": "ο", "π": "π", "ρ": "ρ", "ς": "ς", "σ": "σ", "τ": "τ", "υ": "υ", "φ": "φ", "χ": "χ", "ψ": "ψ", "ω": "ω", "ϑ": "ϑ", "ϒ": "ϒ", "ϖ": "ϖ", "•": "•", "…": "…", "′": "′", "″": "″", "‾": "‾", "⁄": "⁄", "℘": "℘", "ℑ": "ℑ", "ℜ": "ℜ", "™": "™", "ℵ": "ℵ", "←": "←", "↑": "↑", "→": "→", "↓": "↓", "↔": "↔", "↵": "↵", "⇐": "⇐", "⇑": "⇑", "⇒": "⇒", "⇓": "⇓", "⇔": "⇔", "∀": "∀", "∂": "∂", "∃": "∃", "∅": "∅", "∇": "∇", "∈": "∈", "∉": "∉", "∋": "∋", "∏": "∏", "∑": "∑", "−": "−", "∗": "∗", "√": "√", "∝": "∝", "∞": "∞", "∠": "∠", "∧": "∧", "∨": "∨", "∩": "∩", "∪": "∪", "∫": "∫", "∴": "∴", "∼": "∼", "≅": "≅", "≈": "≈", "≠": "≠", "≡": "≡", "≤": "≤", "≥": "≥", "⊂": "⊂", "⊃": "⊃", "⊄": "⊄", "⊆": "⊆", "⊇": "⊇", "⊕": "⊕", "⊗": "⊗", "⊥": "⊥", "⋅": "⋅", "⌈": "⌈", "⌉": "⌉", "⌊": "⌊", "⌋": "⌋", "⟨": "〈", "⟩": "〉", "◊": "◊", "♠": "♠", "♣": "♣", "♥": "♥", "♦": "♦" }, characters: { "'": "'", " ": " ", "¡": "¡", "¢": "¢", "£": "£", "¤": "¤", "¥": "¥", "¦": "¦", "§": "§", "¨": "¨", "©": "©", "ª": "ª", "«": "«", "¬": "¬", "­": "­", "®": "®", "¯": "¯", "°": "°", "±": "±", "²": "²", "³": "³", "´": "´", "µ": "µ", "¶": "¶", "·": "·", "¸": "¸", "¹": "¹", "º": "º", "»": "»", "¼": "¼", "½": "½", "¾": "¾", "¿": "¿", "À": "À", "Á": "Á", "Â": "Â", "Ã": "Ã", "Ä": "Ä", "Å": "Å", "Æ": "Æ", "Ç": "Ç", "È": "È", "É": "É", "Ê": "Ê", "Ë": "Ë", "Ì": "Ì", "Í": "Í", "Î": "Î", "Ï": "Ï", "Ð": "Ð", "Ñ": "Ñ", "Ò": "Ò", "Ó": "Ó", "Ô": "Ô", "Õ": "Õ", "Ö": "Ö", "×": "×", "Ø": "Ø", "Ù": "Ù", "Ú": "Ú", "Û": "Û", "Ü": "Ü", "Ý": "Ý", "Þ": "Þ", "ß": "ß", "à": "à", "á": "á", "â": "â", "ã": "ã", "ä": "ä", "å": "å", "æ": "æ", "ç": "ç", "è": "è", "é": "é", "ê": "ê", "ë": "ë", "ì": "ì", "í": "í", "î": "î", "ï": "ï", "ð": "ð", "ñ": "ñ", "ò": "ò", "ó": "ó", "ô": "ô", "õ": "õ", "ö": "ö", "÷": "÷", "ø": "ø", "ù": "ù", "ú": "ú", "û": "û", "ü": "ü", "ý": "ý", "þ": "þ", "ÿ": "ÿ", '"': """, "&": "&", "<": "<", ">": ">", "Œ": "Œ", "œ": "œ", "Š": "Š", "š": "š", "Ÿ": "Ÿ", "ˆ": "ˆ", "˜": "˜", " ": " ", " ": " ", " ": " ", "‌": "‌", "‍": "‍", "‎": "‎", "‏": "‏", "–": "–", "—": "—", "‘": "‘", "’": "’", "‚": "‚", "“": "“", "”": "”", "„": "„", "†": "†", "‡": "‡", "‰": "‰", "‹": "‹", "›": "›", "€": "€", "ƒ": "ƒ", "Α": "Α", "Β": "Β", "Γ": "Γ", "Δ": "Δ", "Ε": "Ε", "Ζ": "Ζ", "Η": "Η", "Θ": "Θ", "Ι": "Ι", "Κ": "Κ", "Λ": "Λ", "Μ": "Μ", "Ν": "Ν", "Ξ": "Ξ", "Ο": "Ο", "Π": "Π", "Ρ": "Ρ", "Σ": "Σ", "Τ": "Τ", "Υ": "Υ", "Φ": "Φ", "Χ": "Χ", "Ψ": "Ψ", "Ω": "Ω", "α": "α", "β": "β", "γ": "γ", "δ": "δ", "ε": "ε", "ζ": "ζ", "η": "η", "θ": "θ", "ι": "ι", "κ": "κ", "λ": "λ", "μ": "μ", "ν": "ν", "ξ": "ξ", "ο": "ο", "π": "π", "ρ": "ρ", "ς": "ς", "σ": "σ", "τ": "τ", "υ": "υ", "φ": "φ", "χ": "χ", "ψ": "ψ", "ω": "ω", "ϑ": "ϑ", "ϒ": "ϒ", "ϖ": "ϖ", "•": "•", "…": "…", "′": "′", "″": "″", "‾": "‾", "⁄": "⁄", "℘": "℘", "ℑ": "ℑ", "ℜ": "ℜ", "™": "™", "ℵ": "ℵ", "←": "←", "↑": "↑", "→": "→", "↓": "↓", "↔": "↔", "↵": "↵", "⇐": "⇐", "⇑": "⇑", "⇒": "⇒", "⇓": "⇓", "⇔": "⇔", "∀": "∀", "∂": "∂", "∃": "∃", "∅": "∅", "∇": "∇", "∈": "∈", "∉": "∉", "∋": "∋", "∏": "∏", "∑": "∑", "−": "−", "∗": "∗", "√": "√", "∝": "∝", "∞": "∞", "∠": "∠", "∧": "∧", "∨": "∨", "∩": "∩", "∪": "∪", "∫": "∫", "∴": "∴", "∼": "∼", "≅": "≅", "≈": "≈", "≠": "≠", "≡": "≡", "≤": "≤", "≥": "≥", "⊂": "⊂", "⊃": "⊃", "⊄": "⊄", "⊆": "⊆", "⊇": "⊇", "⊕": "⊕", "⊗": "⊗", "⊥": "⊥", "⋅": "⋅", "⌈": "⌈", "⌉": "⌉", "⌊": "⌊", "⌋": "⌋", "〈": "⟨", "〉": "⟩", "◊": "◊", "♠": "♠", "♣": "♣", "♥": "♥", "♦": "♦" } }, html5: { entities: { "Æ": "Æ", "Æ": "Æ", "&": "&", "&": "&", "Á": "Á", "Á": "Á", "Ă": "Ă", "Â": "Â", "Â": "Â", "А": "А", "𝔄": "𝔄", "À": "À", "À": "À", "Α": "Α", "Ā": "Ā", "⩓": "⩓", "Ą": "Ą", "𝔸": "𝔸", "⁡": "⁡", "Å": "Å", "Å": "Å", "𝒜": "𝒜", "≔": "≔", "Ã": "Ã", "Ã": "Ã", "Ä": "Ä", "Ä": "Ä", "∖": "∖", "⫧": "⫧", "⌆": "⌆", "Б": "Б", "∵": "∵", "ℬ": "ℬ", "Β": "Β", "𝔅": "𝔅", "𝔹": "𝔹", "˘": "˘", "ℬ": "ℬ", "≎": "≎", "Ч": "Ч", "©": "©", "©": "©", "Ć": "Ć", "⋒": "⋒", "ⅅ": "ⅅ", "ℭ": "ℭ", "Č": "Č", "Ç": "Ç", "Ç": "Ç", "Ĉ": "Ĉ", "∰": "∰", "Ċ": "Ċ", "¸": "¸", "·": "·", "ℭ": "ℭ", "Χ": "Χ", "⊙": "⊙", "⊖": "⊖", "⊕": "⊕", "⊗": "⊗", "∲": "∲", "”": "”", "’": "’", "∷": "∷", "⩴": "⩴", "≡": "≡", "∯": "∯", "∮": "∮", "ℂ": "ℂ", "∐": "∐", "∳": "∳", "⨯": "⨯", "𝒞": "𝒞", "⋓": "⋓", "≍": "≍", "ⅅ": "ⅅ", "⤑": "⤑", "Ђ": "Ђ", "Ѕ": "Ѕ", "Џ": "Џ", "‡": "‡", "↡": "↡", "⫤": "⫤", "Ď": "Ď", "Д": "Д", "∇": "∇", "Δ": "Δ", "𝔇": "𝔇", "´": "´", "˙": "˙", "˝": "˝", "`": "`", "˜": "˜", "⋄": "⋄", "ⅆ": "ⅆ", "𝔻": "𝔻", "¨": "¨", "⃜": "⃜", "≐": "≐", "∯": "∯", "¨": "¨", "⇓": "⇓", "⇐": "⇐", "⇔": "⇔", "⫤": "⫤", "⟸": "⟸", "⟺": "⟺", "⟹": "⟹", "⇒": "⇒", "⊨": "⊨", "⇑": "⇑", "⇕": "⇕", "∥": "∥", "↓": "↓", "⤓": "⤓", "⇵": "⇵", "̑": "̑", "⥐": "⥐", "⥞": "⥞", "↽": "↽", "⥖": "⥖", "⥟": "⥟", "⇁": "⇁", "⥗": "⥗", "⊤": "⊤", "↧": "↧", "⇓": "⇓", "𝒟": "𝒟", "Đ": "Đ", "Ŋ": "Ŋ", "Ð": "Ð", "Ð": "Ð", "É": "É", "É": "É", "Ě": "Ě", "Ê": "Ê", "Ê": "Ê", "Э": "Э", "Ė": "Ė", "𝔈": "𝔈", "È": "È", "È": "È", "∈": "∈", "Ē": "Ē", "◻": "◻", "▫": "▫", "Ę": "Ę", "𝔼": "𝔼", "Ε": "Ε", "⩵": "⩵", "≂": "≂", "⇌": "⇌", "ℰ": "ℰ", "⩳": "⩳", "Η": "Η", "Ë": "Ë", "Ë": "Ë", "∃": "∃", "ⅇ": "ⅇ", "Ф": "Ф", "𝔉": "𝔉", "◼": "◼", "▪": "▪", "𝔽": "𝔽", "∀": "∀", "ℱ": "ℱ", "ℱ": "ℱ", "Ѓ": "Ѓ", ">": ">", ">": ">", "Γ": "Γ", "Ϝ": "Ϝ", "Ğ": "Ğ", "Ģ": "Ģ", "Ĝ": "Ĝ", "Г": "Г", "Ġ": "Ġ", "𝔊": "𝔊", "⋙": "⋙", "𝔾": "𝔾", "≥": "≥", "⋛": "⋛", "≧": "≧", "⪢": "⪢", "≷": "≷", "⩾": "⩾", "≳": "≳", "𝒢": "𝒢", "≫": "≫", "Ъ": "Ъ", "ˇ": "ˇ", "^": "^", "Ĥ": "Ĥ", "ℌ": "ℌ", "ℋ": "ℋ", "ℍ": "ℍ", "─": "─", "ℋ": "ℋ", "Ħ": "Ħ", "≎": "≎", "≏": "≏", "Е": "Е", "IJ": "IJ", "Ё": "Ё", "Í": "Í", "Í": "Í", "Î": "Î", "Î": "Î", "И": "И", "İ": "İ", "ℑ": "ℑ", "Ì": "Ì", "Ì": "Ì", "ℑ": "ℑ", "Ī": "Ī", "ⅈ": "ⅈ", "⇒": "⇒", "∬": "∬", "∫": "∫", "⋂": "⋂", "⁣": "⁣", "⁢": "⁢", "Į": "Į", "𝕀": "𝕀", "Ι": "Ι", "ℐ": "ℐ", "Ĩ": "Ĩ", "І": "І", "Ï": "Ï", "Ï": "Ï", "Ĵ": "Ĵ", "Й": "Й", "𝔍": "𝔍", "𝕁": "𝕁", "𝒥": "𝒥", "Ј": "Ј", "Є": "Є", "Х": "Х", "Ќ": "Ќ", "Κ": "Κ", "Ķ": "Ķ", "К": "К", "𝔎": "𝔎", "𝕂": "𝕂", "𝒦": "𝒦", "Љ": "Љ", "<": "<", "<": "<", "Ĺ": "Ĺ", "Λ": "Λ", "⟪": "⟪", "ℒ": "ℒ", "↞": "↞", "Ľ": "Ľ", "Ļ": "Ļ", "Л": "Л", "⟨": "⟨", "←": "←", "⇤": "⇤", "⇆": "⇆", "⌈": "⌈", "⟦": "⟦", "⥡": "⥡", "⇃": "⇃", "⥙": "⥙", "⌊": "⌊", "↔": "↔", "⥎": "⥎", "⊣": "⊣", "↤": "↤", "⥚": "⥚", "⊲": "⊲", "⧏": "⧏", "⊴": "⊴", "⥑": "⥑", "⥠": "⥠", "↿": "↿", "⥘": "⥘", "↼": "↼", "⥒": "⥒", "⇐": "⇐", "⇔": "⇔", "⋚": "⋚", "≦": "≦", "≶": "≶", "⪡": "⪡", "⩽": "⩽", "≲": "≲", "𝔏": "𝔏", "⋘": "⋘", "⇚": "⇚", "Ŀ": "Ŀ", "⟵": "⟵", "⟷": "⟷", "⟶": "⟶", "⟸": "⟸", "⟺": "⟺", "⟹": "⟹", "𝕃": "𝕃", "↙": "↙", "↘": "↘", "ℒ": "ℒ", "↰": "↰", "Ł": "Ł", "≪": "≪", "⤅": "⤅", "М": "М", " ": " ", "ℳ": "ℳ", "𝔐": "𝔐", "∓": "∓", "𝕄": "𝕄", "ℳ": "ℳ", "Μ": "Μ", "Њ": "Њ", "Ń": "Ń", "Ň": "Ň", "Ņ": "Ņ", "Н": "Н", "​": "​", "​": "​", "​": "​", "​": "​", "≫": "≫", "≪": "≪", " ": "\n", "𝔑": "𝔑", "⁠": "⁠", " ": " ", "ℕ": "ℕ", "⫬": "⫬", "≢": "≢", "≭": "≭", "∦": "∦", "∉": "∉", "≠": "≠", "≂̸": "≂̸", "∄": "∄", "≯": "≯", "≱": "≱", "≧̸": "≧̸", "≫̸": "≫̸", "≹": "≹", "⩾̸": "⩾̸", "≵": "≵", "≎̸": "≎̸", "≏̸": "≏̸", "⋪": "⋪", "⧏̸": "⧏̸", "⋬": "⋬", "≮": "≮", "≰": "≰", "≸": "≸", "≪̸": "≪̸", "⩽̸": "⩽̸", "≴": "≴", "⪢̸": "⪢̸", "⪡̸": "⪡̸", "⊀": "⊀", "⪯̸": "⪯̸", "⋠": "⋠", "∌": "∌", "⋫": "⋫", "⧐̸": "⧐̸", "⋭": "⋭", "⊏̸": "⊏̸", "⋢": "⋢", "⊐̸": "⊐̸", "⋣": "⋣", "⊂⃒": "⊂⃒", "⊈": "⊈", "⊁": "⊁", "⪰̸": "⪰̸", "⋡": "⋡", "≿̸": "≿̸", "⊃⃒": "⊃⃒", "⊉": "⊉", "≁": "≁", "≄": "≄", "≇": "≇", "≉": "≉", "∤": "∤", "𝒩": "𝒩", "Ñ": "Ñ", "Ñ": "Ñ", "Ν": "Ν", "Œ": "Œ", "Ó": "Ó", "Ó": "Ó", "Ô": "Ô", "Ô": "Ô", "О": "О", "Ő": "Ő", "𝔒": "𝔒", "Ò": "Ò", "Ò": "Ò", "Ō": "Ō", "Ω": "Ω", "Ο": "Ο", "𝕆": "𝕆", "“": "“", "‘": "‘", "⩔": "⩔", "𝒪": "𝒪", "Ø": "Ø", "Ø": "Ø", "Õ": "Õ", "Õ": "Õ", "⨷": "⨷", "Ö": "Ö", "Ö": "Ö", "‾": "‾", "⏞": "⏞", "⎴": "⎴", "⏜": "⏜", "∂": "∂", "П": "П", "𝔓": "𝔓", "Φ": "Φ", "Π": "Π", "±": "±", "ℌ": "ℌ", "ℙ": "ℙ", "⪻": "⪻", "≺": "≺", "⪯": "⪯", "≼": "≼", "≾": "≾", "″": "″", "∏": "∏", "∷": "∷", "∝": "∝", "𝒫": "𝒫", "Ψ": "Ψ", """: '"', """: '"', "𝔔": "𝔔", "ℚ": "ℚ", "𝒬": "𝒬", "⤐": "⤐", "®": "®", "®": "®", "Ŕ": "Ŕ", "⟫": "⟫", "↠": "↠", "⤖": "⤖", "Ř": "Ř", "Ŗ": "Ŗ", "Р": "Р", "ℜ": "ℜ", "∋": "∋", "⇋": "⇋", "⥯": "⥯", "ℜ": "ℜ", "Ρ": "Ρ", "⟩": "⟩", "→": "→", "⇥": "⇥", "⇄": "⇄", "⌉": "⌉", "⟧": "⟧", "⥝": "⥝", "⇂": "⇂", "⥕": "⥕", "⌋": "⌋", "⊢": "⊢", "↦": "↦", "⥛": "⥛", "⊳": "⊳", "⧐": "⧐", "⊵": "⊵", "⥏": "⥏", "⥜": "⥜", "↾": "↾", "⥔": "⥔", "⇀": "⇀", "⥓": "⥓", "⇒": "⇒", "ℝ": "ℝ", "⥰": "⥰", "⇛": "⇛", "ℛ": "ℛ", "↱": "↱", "⧴": "⧴", "Щ": "Щ", "Ш": "Ш", "Ь": "Ь", "Ś": "Ś", "⪼": "⪼", "Š": "Š", "Ş": "Ş", "Ŝ": "Ŝ", "С": "С", "𝔖": "𝔖", "↓": "↓", "←": "←", "→": "→", "↑": "↑", "Σ": "Σ", "∘": "∘", "𝕊": "𝕊", "√": "√", "□": "□", "⊓": "⊓", "⊏": "⊏", "⊑": "⊑", "⊐": "⊐", "⊒": "⊒", "⊔": "⊔", "𝒮": "𝒮", "⋆": "⋆", "⋐": "⋐", "⋐": "⋐", "⊆": "⊆", "≻": "≻", "⪰": "⪰", "≽": "≽", "≿": "≿", "∋": "∋", "∑": "∑", "⋑": "⋑", "⊃": "⊃", "⊇": "⊇", "⋑": "⋑", "Þ": "Þ", "Þ": "Þ", "™": "™", "Ћ": "Ћ", "Ц": "Ц", " ": " ", "Τ": "Τ", "Ť": "Ť", "Ţ": "Ţ", "Т": "Т", "𝔗": "𝔗", "∴": "∴", "Θ": "Θ", "  ": "  ", " ": " ", "∼": "∼", "≃": "≃", "≅": "≅", "≈": "≈", "𝕋": "𝕋", "⃛": "⃛", "𝒯": "𝒯", "Ŧ": "Ŧ", "Ú": "Ú", "Ú": "Ú", "↟": "↟", "⥉": "⥉", "Ў": "Ў", "Ŭ": "Ŭ", "Û": "Û", "Û": "Û", "У": "У", "Ű": "Ű", "𝔘": "𝔘", "Ù": "Ù", "Ù": "Ù", "Ū": "Ū", "_": "_", "⏟": "⏟", "⎵": "⎵", "⏝": "⏝", "⋃": "⋃", "⊎": "⊎", "Ų": "Ų", "𝕌": "𝕌", "↑": "↑", "⤒": "⤒", "⇅": "⇅", "↕": "↕", "⥮": "⥮", "⊥": "⊥", "↥": "↥", "⇑": "⇑", "⇕": "⇕", "↖": "↖", "↗": "↗", "ϒ": "ϒ", "Υ": "Υ", "Ů": "Ů", "𝒰": "𝒰", "Ũ": "Ũ", "Ü": "Ü", "Ü": "Ü", "⊫": "⊫", "⫫": "⫫", "В": "В", "⊩": "⊩", "⫦": "⫦", "⋁": "⋁", "‖": "‖", "‖": "‖", "∣": "∣", "|": "|", "❘": "❘", "≀": "≀", " ": " ", "𝔙": "𝔙", "𝕍": "𝕍", "𝒱": "𝒱", "⊪": "⊪", "Ŵ": "Ŵ", "⋀": "⋀", "𝔚": "𝔚", "𝕎": "𝕎", "𝒲": "𝒲", "𝔛": "𝔛", "Ξ": "Ξ", "𝕏": "𝕏", "𝒳": "𝒳", "Я": "Я", "Ї": "Ї", "Ю": "Ю", "Ý": "Ý", "Ý": "Ý", "Ŷ": "Ŷ", "Ы": "Ы", "𝔜": "𝔜", "𝕐": "𝕐", "𝒴": "𝒴", "Ÿ": "Ÿ", "Ж": "Ж", "Ź": "Ź", "Ž": "Ž", "З": "З", "Ż": "Ż", "​": "​", "Ζ": "Ζ", "ℨ": "ℨ", "ℤ": "ℤ", "𝒵": "𝒵", "á": "á", "á": "á", "ă": "ă", "∾": "∾", "∾̳": "∾̳", "∿": "∿", "â": "â", "â": "â", "´": "´", "´": "´", "а": "а", "æ": "æ", "æ": "æ", "⁡": "⁡", "𝔞": "𝔞", "à": "à", "à": "à", "ℵ": "ℵ", "ℵ": "ℵ", "α": "α", "ā": "ā", "⨿": "⨿", "&": "&", "&": "&", "∧": "∧", "⩕": "⩕", "⩜": "⩜", "⩘": "⩘", "⩚": "⩚", "∠": "∠", "⦤": "⦤", "∠": "∠", "∡": "∡", "⦨": "⦨", "⦩": "⦩", "⦪": "⦪", "⦫": "⦫", "⦬": "⦬", "⦭": "⦭", "⦮": "⦮", "⦯": "⦯", "∟": "∟", "⊾": "⊾", "⦝": "⦝", "∢": "∢", "Å": "Å", "⍼": "⍼", "ą": "ą", "𝕒": "𝕒", "≈": "≈", "⩰": "⩰", "⩯": "⩯", "≊": "≊", "≋": "≋", "'": "'", "≈": "≈", "≊": "≊", "å": "å", "å": "å", "𝒶": "𝒶", "*": "*", "≈": "≈", "≍": "≍", "ã": "ã", "ã": "ã", "ä": "ä", "ä": "ä", "∳": "∳", "⨑": "⨑", "⫭": "⫭", "≌": "≌", "϶": "϶", "‵": "‵", "∽": "∽", "⋍": "⋍", "⊽": "⊽", "⌅": "⌅", "⌅": "⌅", "⎵": "⎵", "⎶": "⎶", "≌": "≌", "б": "б", "„": "„", "∵": "∵", "∵": "∵", "⦰": "⦰", "϶": "϶", "ℬ": "ℬ", "β": "β", "ℶ": "ℶ", "≬": "≬", "𝔟": "𝔟", "⋂": "⋂", "◯": "◯", "⋃": "⋃", "⨀": "⨀", "⨁": "⨁", "⨂": "⨂", "⨆": "⨆", "★": "★", "▽": "▽", "△": "△", "⨄": "⨄", "⋁": "⋁", "⋀": "⋀", "⤍": "⤍", "⧫": "⧫", "▪": "▪", "▴": "▴", "▾": "▾", "◂": "◂", "▸": "▸", "␣": "␣", "▒": "▒", "░": "░", "▓": "▓", "█": "█", "=⃥": "=⃥", "≡⃥": "≡⃥", "⌐": "⌐", "𝕓": "𝕓", "⊥": "⊥", "⊥": "⊥", "⋈": "⋈", "╗": "╗", "╔": "╔", "╖": "╖", "╓": "╓", "═": "═", "╦": "╦", "╩": "╩", "╤": "╤", "╧": "╧", "╝": "╝", "╚": "╚", "╜": "╜", "╙": "╙", "║": "║", "╬": "╬", "╣": "╣", "╠": "╠", "╫": "╫", "╢": "╢", "╟": "╟", "⧉": "⧉", "╕": "╕", "╒": "╒", "┐": "┐", "┌": "┌", "─": "─", "╥": "╥", "╨": "╨", "┬": "┬", "┴": "┴", "⊟": "⊟", "⊞": "⊞", "⊠": "⊠", "╛": "╛", "╘": "╘", "┘": "┘", "└": "└", "│": "│", "╪": "╪", "╡": "╡", "╞": "╞", "┼": "┼", "┤": "┤", "├": "├", "‵": "‵", "˘": "˘", "¦": "¦", "¦": "¦", "𝒷": "𝒷", "⁏": "⁏", "∽": "∽", "⋍": "⋍", "\": "\\", "⧅": "⧅", "⟈": "⟈", "•": "•", "•": "•", "≎": "≎", "⪮": "⪮", "≏": "≏", "≏": "≏", "ć": "ć", "∩": "∩", "⩄": "⩄", "⩉": "⩉", "⩋": "⩋", "⩇": "⩇", "⩀": "⩀", "∩︀": "∩︀", "⁁": "⁁", "ˇ": "ˇ", "⩍": "⩍", "č": "č", "ç": "ç", "ç": "ç", "ĉ": "ĉ", "⩌": "⩌", "⩐": "⩐", "ċ": "ċ", "¸": "¸", "¸": "¸", "⦲": "⦲", "¢": "¢", "¢": "¢", "·": "·", "𝔠": "𝔠", "ч": "ч", "✓": "✓", "✓": "✓", "χ": "χ", "○": "○", "⧃": "⧃", "ˆ": "ˆ", "≗": "≗", "↺": "↺", "↻": "↻", "®": "®", "Ⓢ": "Ⓢ", "⊛": "⊛", "⊚": "⊚", "⊝": "⊝", "≗": "≗", "⨐": "⨐", "⫯": "⫯", "⧂": "⧂", "♣": "♣", "♣": "♣", ":": ":", "≔": "≔", "≔": "≔", ",": ",", "@": "@", "∁": "∁", "∘": "∘", "∁": "∁", "ℂ": "ℂ", "≅": "≅", "⩭": "⩭", "∮": "∮", "𝕔": "𝕔", "∐": "∐", "©": "©", "©": "©", "℗": "℗", "↵": "↵", "✗": "✗", "𝒸": "𝒸", "⫏": "⫏", "⫑": "⫑", "⫐": "⫐", "⫒": "⫒", "⋯": "⋯", "⤸": "⤸", "⤵": "⤵", "⋞": "⋞", "⋟": "⋟", "↶": "↶", "⤽": "⤽", "∪": "∪", "⩈": "⩈", "⩆": "⩆", "⩊": "⩊", "⊍": "⊍", "⩅": "⩅", "∪︀": "∪︀", "↷": "↷", "⤼": "⤼", "⋞": "⋞", "⋟": "⋟", "⋎": "⋎", "⋏": "⋏", "¤": "¤", "¤": "¤", "↶": "↶", "↷": "↷", "⋎": "⋎", "⋏": "⋏", "∲": "∲", "∱": "∱", "⌭": "⌭", "⇓": "⇓", "⥥": "⥥", "†": "†", "ℸ": "ℸ", "↓": "↓", "‐": "‐", "⊣": "⊣", "⤏": "⤏", "˝": "˝", "ď": "ď", "д": "д", "ⅆ": "ⅆ", "‡": "‡", "⇊": "⇊", "⩷": "⩷", "°": "°", "°": "°", "δ": "δ", "⦱": "⦱", "⥿": "⥿", "𝔡": "𝔡", "⇃": "⇃", "⇂": "⇂", "⋄": "⋄", "⋄": "⋄", "♦": "♦", "♦": "♦", "¨": "¨", "ϝ": "ϝ", "⋲": "⋲", "÷": "÷", "÷": "÷", "÷": "÷", "⋇": "⋇", "⋇": "⋇", "ђ": "ђ", "⌞": "⌞", "⌍": "⌍", "$": "$", "𝕕": "𝕕", "˙": "˙", "≐": "≐", "≑": "≑", "∸": "∸", "∔": "∔", "⊡": "⊡", "⌆": "⌆", "↓": "↓", "⇊": "⇊", "⇃": "⇃", "⇂": "⇂", "⤐": "⤐", "⌟": "⌟", "⌌": "⌌", "𝒹": "𝒹", "ѕ": "ѕ", "⧶": "⧶", "đ": "đ", "⋱": "⋱", "▿": "▿", "▾": "▾", "⇵": "⇵", "⥯": "⥯", "⦦": "⦦", "џ": "џ", "⟿": "⟿", "⩷": "⩷", "≑": "≑", "é": "é", "é": "é", "⩮": "⩮", "ě": "ě", "≖": "≖", "ê": "ê", "ê": "ê", "≕": "≕", "э": "э", "ė": "ė", "ⅇ": "ⅇ", "≒": "≒", "𝔢": "𝔢", "⪚": "⪚", "è": "è", "è": "è", "⪖": "⪖", "⪘": "⪘", "⪙": "⪙", "⏧": "⏧", "ℓ": "ℓ", "⪕": "⪕", "⪗": "⪗", "ē": "ē", "∅": "∅", "∅": "∅", "∅": "∅", " ": " ", " ": " ", " ": " ", "ŋ": "ŋ", " ": " ", "ę": "ę", "𝕖": "𝕖", "⋕": "⋕", "⧣": "⧣", "⩱": "⩱", "ε": "ε", "ε": "ε", "ϵ": "ϵ", "≖": "≖", "≕": "≕", "≂": "≂", "⪖": "⪖", "⪕": "⪕", "=": "=", "≟": "≟", "≡": "≡", "⩸": "⩸", "⧥": "⧥", "≓": "≓", "⥱": "⥱", "ℯ": "ℯ", "≐": "≐", "≂": "≂", "η": "η", "ð": "ð", "ð": "ð", "ë": "ë", "ë": "ë", "€": "€", "!": "!", "∃": "∃", "ℰ": "ℰ", "ⅇ": "ⅇ", "≒": "≒", "ф": "ф", "♀": "♀", "ffi": "ffi", "ff": "ff", "ffl": "ffl", "𝔣": "𝔣", "fi": "fi", "fj": "fj", "♭": "♭", "fl": "fl", "▱": "▱", "ƒ": "ƒ", "𝕗": "𝕗", "∀": "∀", "⋔": "⋔", "⫙": "⫙", "⨍": "⨍", "½": "½", "½": "½", "⅓": "⅓", "¼": "¼", "¼": "¼", "⅕": "⅕", "⅙": "⅙", "⅛": "⅛", "⅔": "⅔", "⅖": "⅖", "¾": "¾", "¾": "¾", "⅗": "⅗", "⅜": "⅜", "⅘": "⅘", "⅚": "⅚", "⅝": "⅝", "⅞": "⅞", "⁄": "⁄", "⌢": "⌢", "𝒻": "𝒻", "≧": "≧", "⪌": "⪌", "ǵ": "ǵ", "γ": "γ", "ϝ": "ϝ", "⪆": "⪆", "ğ": "ğ", "ĝ": "ĝ", "г": "г", "ġ": "ġ", "≥": "≥", "⋛": "⋛", "≥": "≥", "≧": "≧", "⩾": "⩾", "⩾": "⩾", "⪩": "⪩", "⪀": "⪀", "⪂": "⪂", "⪄": "⪄", "⋛︀": "⋛︀", "⪔": "⪔", "𝔤": "𝔤", "≫": "≫", "⋙": "⋙", "ℷ": "ℷ", "ѓ": "ѓ", "≷": "≷", "⪒": "⪒", "⪥": "⪥", "⪤": "⪤", "≩": "≩", "⪊": "⪊", "⪊": "⪊", "⪈": "⪈", "⪈": "⪈", "≩": "≩", "⋧": "⋧", "𝕘": "𝕘", "`": "`", "ℊ": "ℊ", "≳": "≳", "⪎": "⪎", "⪐": "⪐", ">": ">", ">": ">", "⪧": "⪧", "⩺": "⩺", "⋗": "⋗", "⦕": "⦕", "⩼": "⩼", "⪆": "⪆", "⥸": "⥸", "⋗": "⋗", "⋛": "⋛", "⪌": "⪌", "≷": "≷", "≳": "≳", "≩︀": "≩︀", "≩︀": "≩︀", "⇔": "⇔", " ": " ", "½": "½", "ℋ": "ℋ", "ъ": "ъ", "↔": "↔", "⥈": "⥈", "↭": "↭", "ℏ": "ℏ", "ĥ": "ĥ", "♥": "♥", "♥": "♥", "…": "…", "⊹": "⊹", "𝔥": "𝔥", "⤥": "⤥", "⤦": "⤦", "⇿": "⇿", "∻": "∻", "↩": "↩", "↪": "↪", "𝕙": "𝕙", "―": "―", "𝒽": "𝒽", "ℏ": "ℏ", "ħ": "ħ", "⁃": "⁃", "‐": "‐", "í": "í", "í": "í", "⁣": "⁣", "î": "î", "î": "î", "и": "и", "е": "е", "¡": "¡", "¡": "¡", "⇔": "⇔", "𝔦": "𝔦", "ì": "ì", "ì": "ì", "ⅈ": "ⅈ", "⨌": "⨌", "∭": "∭", "⧜": "⧜", "℩": "℩", "ij": "ij", "ī": "ī", "ℑ": "ℑ", "ℐ": "ℐ", "ℑ": "ℑ", "ı": "ı", "⊷": "⊷", "Ƶ": "Ƶ", "∈": "∈", "℅": "℅", "∞": "∞", "⧝": "⧝", "ı": "ı", "∫": "∫", "⊺": "⊺", "ℤ": "ℤ", "⊺": "⊺", "⨗": "⨗", "⨼": "⨼", "ё": "ё", "į": "į", "𝕚": "𝕚", "ι": "ι", "⨼": "⨼", "¿": "¿", "¿": "¿", "𝒾": "𝒾", "∈": "∈", "⋹": "⋹", "⋵": "⋵", "⋴": "⋴", "⋳": "⋳", "∈": "∈", "⁢": "⁢", "ĩ": "ĩ", "і": "і", "ï": "ï", "ï": "ï", "ĵ": "ĵ", "й": "й", "𝔧": "𝔧", "ȷ": "ȷ", "𝕛": "𝕛", "𝒿": "𝒿", "ј": "ј", "є": "є", "κ": "κ", "ϰ": "ϰ", "ķ": "ķ", "к": "к", "𝔨": "𝔨", "ĸ": "ĸ", "х": "х", "ќ": "ќ", "𝕜": "𝕜", "𝓀": "𝓀", "⇚": "⇚", "⇐": "⇐", "⤛": "⤛", "⤎": "⤎", "≦": "≦", "⪋": "⪋", "⥢": "⥢", "ĺ": "ĺ", "⦴": "⦴", "ℒ": "ℒ", "λ": "λ", "⟨": "⟨", "⦑": "⦑", "⟨": "⟨", "⪅": "⪅", "«": "«", "«": "«", "←": "←", "⇤": "⇤", "⤟": "⤟", "⤝": "⤝", "↩": "↩", "↫": "↫", "⤹": "⤹", "⥳": "⥳", "↢": "↢", "⪫": "⪫", "⤙": "⤙", "⪭": "⪭", "⪭︀": "⪭︀", "⤌": "⤌", "❲": "❲", "{": "{", "[": "[", "⦋": "⦋", "⦏": "⦏", "⦍": "⦍", "ľ": "ľ", "ļ": "ļ", "⌈": "⌈", "{": "{", "л": "л", "⤶": "⤶", "“": "“", "„": "„", "⥧": "⥧", "⥋": "⥋", "↲": "↲", "≤": "≤", "←": "←", "↢": "↢", "↽": "↽", "↼": "↼", "⇇": "⇇", "↔": "↔", "⇆": "⇆", "⇋": "⇋", "↭": "↭", "⋋": "⋋", "⋚": "⋚", "≤": "≤", "≦": "≦", "⩽": "⩽", "⩽": "⩽", "⪨": "⪨", "⩿": "⩿", "⪁": "⪁", "⪃": "⪃", "⋚︀": "⋚︀", "⪓": "⪓", "⪅": "⪅", "⋖": "⋖", "⋚": "⋚", "⪋": "⪋", "≶": "≶", "≲": "≲", "⥼": "⥼", "⌊": "⌊", "𝔩": "𝔩", "≶": "≶", "⪑": "⪑", "↽": "↽", "↼": "↼", "⥪": "⥪", "▄": "▄", "љ": "љ", "≪": "≪", "⇇": "⇇", "⌞": "⌞", "⥫": "⥫", "◺": "◺", "ŀ": "ŀ", "⎰": "⎰", "⎰": "⎰", "≨": "≨", "⪉": "⪉", "⪉": "⪉", "⪇": "⪇", "⪇": "⪇", "≨": "≨", "⋦": "⋦", "⟬": "⟬", "⇽": "⇽", "⟦": "⟦", "⟵": "⟵", "⟷": "⟷", "⟼": "⟼", "⟶": "⟶", "↫": "↫", "↬": "↬", "⦅": "⦅", "𝕝": "𝕝", "⨭": "⨭", "⨴": "⨴", "∗": "∗", "_": "_", "◊": "◊", "◊": "◊", "⧫": "⧫", "(": "(", "⦓": "⦓", "⇆": "⇆", "⌟": "⌟", "⇋": "⇋", "⥭": "⥭", "‎": "‎", "⊿": "⊿", "‹": "‹", "𝓁": "𝓁", "↰": "↰", "≲": "≲", "⪍": "⪍", "⪏": "⪏", "[": "[", "‘": "‘", "‚": "‚", "ł": "ł", "<": "<", "<": "<", "⪦": "⪦", "⩹": "⩹", "⋖": "⋖", "⋋": "⋋", "⋉": "⋉", "⥶": "⥶", "⩻": "⩻", "⦖": "⦖", "◃": "◃", "⊴": "⊴", "◂": "◂", "⥊": "⥊", "⥦": "⥦", "≨︀": "≨︀", "≨︀": "≨︀", "∺": "∺", "¯": "¯", "¯": "¯", "♂": "♂", "✠": "✠", "✠": "✠", "↦": "↦", "↦": "↦", "↧": "↧", "↤": "↤", "↥": "↥", "▮": "▮", "⨩": "⨩", "м": "м", "—": "—", "∡": "∡", "𝔪": "𝔪", "℧": "℧", "µ": "µ", "µ": "µ", "∣": "∣", "*": "*", "⫰": "⫰", "·": "·", "·": "·", "−": "−", "⊟": "⊟", "∸": "∸", "⨪": "⨪", "⫛": "⫛", "…": "…", "∓": "∓", "⊧": "⊧", "𝕞": "𝕞", "∓": "∓", "𝓂": "𝓂", "∾": "∾", "μ": "μ", "⊸": "⊸", "⊸": "⊸", "⋙̸": "⋙̸", "≫⃒": "≫⃒", "≫̸": "≫̸", "⇍": "⇍", "⇎": "⇎", "⋘̸": "⋘̸", "≪⃒": "≪⃒", "≪̸": "≪̸", "⇏": "⇏", "⊯": "⊯", "⊮": "⊮", "∇": "∇", "ń": "ń", "∠⃒": "∠⃒", "≉": "≉", "⩰̸": "⩰̸", "≋̸": "≋̸", "ʼn": "ʼn", "≉": "≉", "♮": "♮", "♮": "♮", "ℕ": "ℕ", " ": " ", " ": " ", "≎̸": "≎̸", "≏̸": "≏̸", "⩃": "⩃", "ň": "ň", "ņ": "ņ", "≇": "≇", "⩭̸": "⩭̸", "⩂": "⩂", "н": "н", "–": "–", "≠": "≠", "⇗": "⇗", "⤤": "⤤", "↗": "↗", "↗": "↗", "≐̸": "≐̸", "≢": "≢", "⤨": "⤨", "≂̸": "≂̸", "∄": "∄", "∄": "∄", "𝔫": "𝔫", "≧̸": "≧̸", "≱": "≱", "≱": "≱", "≧̸": "≧̸", "⩾̸": "⩾̸", "⩾̸": "⩾̸", "≵": "≵", "≯": "≯", "≯": "≯", "⇎": "⇎", "↮": "↮", "⫲": "⫲", "∋": "∋", "⋼": "⋼", "⋺": "⋺", "∋": "∋", "њ": "њ", "⇍": "⇍", "≦̸": "≦̸", "↚": "↚", "‥": "‥", "≰": "≰", "↚": "↚", "↮": "↮", "≰": "≰", "≦̸": "≦̸", "⩽̸": "⩽̸", "⩽̸": "⩽̸", "≮": "≮", "≴": "≴", "≮": "≮", "⋪": "⋪", "⋬": "⋬", "∤": "∤", "𝕟": "𝕟", "¬": "¬", "¬": "¬", "∉": "∉", "⋹̸": "⋹̸", "⋵̸": "⋵̸", "∉": "∉", "⋷": "⋷", "⋶": "⋶", "∌": "∌", "∌": "∌", "⋾": "⋾", "⋽": "⋽", "∦": "∦", "∦": "∦", "⫽⃥": "⫽⃥", "∂̸": "∂̸", "⨔": "⨔", "⊀": "⊀", "⋠": "⋠", "⪯̸": "⪯̸", "⊀": "⊀", "⪯̸": "⪯̸", "⇏": "⇏", "↛": "↛", "⤳̸": "⤳̸", "↝̸": "↝̸", "↛": "↛", "⋫": "⋫", "⋭": "⋭", "⊁": "⊁", "⋡": "⋡", "⪰̸": "⪰̸", "𝓃": "𝓃", "∤": "∤", "∦": "∦", "≁": "≁", "≄": "≄", "≄": "≄", "∤": "∤", "∦": "∦", "⋢": "⋢", "⋣": "⋣", "⊄": "⊄", "⫅̸": "⫅̸", "⊈": "⊈", "⊂⃒": "⊂⃒", "⊈": "⊈", "⫅̸": "⫅̸", "⊁": "⊁", "⪰̸": "⪰̸", "⊅": "⊅", "⫆̸": "⫆̸", "⊉": "⊉", "⊃⃒": "⊃⃒", "⊉": "⊉", "⫆̸": "⫆̸", "≹": "≹", "ñ": "ñ", "ñ": "ñ", "≸": "≸", "⋪": "⋪", "⋬": "⋬", "⋫": "⋫", "⋭": "⋭", "ν": "ν", "#": "#", "№": "№", " ": " ", "⊭": "⊭", "⤄": "⤄", "≍⃒": "≍⃒", "⊬": "⊬", "≥⃒": "≥⃒", ">⃒": ">⃒", "⧞": "⧞", "⤂": "⤂", "≤⃒": "≤⃒", "<⃒": "<⃒", "⊴⃒": "⊴⃒", "⤃": "⤃", "⊵⃒": "⊵⃒", "∼⃒": "∼⃒", "⇖": "⇖", "⤣": "⤣", "↖": "↖", "↖": "↖", "⤧": "⤧", "Ⓢ": "Ⓢ", "ó": "ó", "ó": "ó", "⊛": "⊛", "⊚": "⊚", "ô": "ô", "ô": "ô", "о": "о", "⊝": "⊝", "ő": "ő", "⨸": "⨸", "⊙": "⊙", "⦼": "⦼", "œ": "œ", "⦿": "⦿", "𝔬": "𝔬", "˛": "˛", "ò": "ò", "ò": "ò", "⧁": "⧁", "⦵": "⦵", "Ω": "Ω", "∮": "∮", "↺": "↺", "⦾": "⦾", "⦻": "⦻", "‾": "‾", "⧀": "⧀", "ō": "ō", "ω": "ω", "ο": "ο", "⦶": "⦶", "⊖": "⊖", "𝕠": "𝕠", "⦷": "⦷", "⦹": "⦹", "⊕": "⊕", "∨": "∨", "↻": "↻", "⩝": "⩝", "ℴ": "ℴ", "ℴ": "ℴ", "ª": "ª", "ª": "ª", "º": "º", "º": "º", "⊶": "⊶", "⩖": "⩖", "⩗": "⩗", "⩛": "⩛", "ℴ": "ℴ", "ø": "ø", "ø": "ø", "⊘": "⊘", "õ": "õ", "õ": "õ", "⊗": "⊗", "⨶": "⨶", "ö": "ö", "ö": "ö", "⌽": "⌽", "∥": "∥", "¶": "¶", "¶": "¶", "∥": "∥", "⫳": "⫳", "⫽": "⫽", "∂": "∂", "п": "п", "%": "%", ".": ".", "‰": "‰", "⊥": "⊥", "‱": "‱", "𝔭": "𝔭", "φ": "φ", "ϕ": "ϕ", "ℳ": "ℳ", "☎": "☎", "π": "π", "⋔": "⋔", "ϖ": "ϖ", "ℏ": "ℏ", "ℎ": "ℎ", "ℏ": "ℏ", "+": "+", "⨣": "⨣", "⊞": "⊞", "⨢": "⨢", "∔": "∔", "⨥": "⨥", "⩲": "⩲", "±": "±", "±": "±", "⨦": "⨦", "⨧": "⨧", "±": "±", "⨕": "⨕", "𝕡": "𝕡", "£": "£", "£": "£", "≺": "≺", "⪳": "⪳", "⪷": "⪷", "≼": "≼", "⪯": "⪯", "≺": "≺", "⪷": "⪷", "≼": "≼", "⪯": "⪯", "⪹": "⪹", "⪵": "⪵", "⋨": "⋨", "≾": "≾", "′": "′", "ℙ": "ℙ", "⪵": "⪵", "⪹": "⪹", "⋨": "⋨", "∏": "∏", "⌮": "⌮", "⌒": "⌒", "⌓": "⌓", "∝": "∝", "∝": "∝", "≾": "≾", "⊰": "⊰", "𝓅": "𝓅", "ψ": "ψ", " ": " ", "𝔮": "𝔮", "⨌": "⨌", "𝕢": "𝕢", "⁗": "⁗", "𝓆": "𝓆", "ℍ": "ℍ", "⨖": "⨖", "?": "?", "≟": "≟", """: '"', """: '"', "⇛": "⇛", "⇒": "⇒", "⤜": "⤜", "⤏": "⤏", "⥤": "⥤", "∽̱": "∽̱", "ŕ": "ŕ", "√": "√", "⦳": "⦳", "⟩": "⟩", "⦒": "⦒", "⦥": "⦥", "⟩": "⟩", "»": "»", "»": "»", "→": "→", "⥵": "⥵", "⇥": "⇥", "⤠": "⤠", "⤳": "⤳", "⤞": "⤞", "↪": "↪", "↬": "↬", "⥅": "⥅", "⥴": "⥴", "↣": "↣", "↝": "↝", "⤚": "⤚", "∶": "∶", "ℚ": "ℚ", "⤍": "⤍", "❳": "❳", "}": "}", "]": "]", "⦌": "⦌", "⦎": "⦎", "⦐": "⦐", "ř": "ř", "ŗ": "ŗ", "⌉": "⌉", "}": "}", "р": "р", "⤷": "⤷", "⥩": "⥩", "”": "”", "”": "”", "↳": "↳", "ℜ": "ℜ", "ℛ": "ℛ", "ℜ": "ℜ", "ℝ": "ℝ", "▭": "▭", "®": "®", "®": "®", "⥽": "⥽", "⌋": "⌋", "𝔯": "𝔯", "⇁": "⇁", "⇀": "⇀", "⥬": "⥬", "ρ": "ρ", "ϱ": "ϱ", "→": "→", "↣": "↣", "⇁": "⇁", "⇀": "⇀", "⇄": "⇄", "⇌": "⇌", "⇉": "⇉", "↝": "↝", "⋌": "⋌", "˚": "˚", "≓": "≓", "⇄": "⇄", "⇌": "⇌", "‏": "‏", "⎱": "⎱", "⎱": "⎱", "⫮": "⫮", "⟭": "⟭", "⇾": "⇾", "⟧": "⟧", "⦆": "⦆", "𝕣": "𝕣", "⨮": "⨮", "⨵": "⨵", ")": ")", "⦔": "⦔", "⨒": "⨒", "⇉": "⇉", "›": "›", "𝓇": "𝓇", "↱": "↱", "]": "]", "’": "’", "’": "’", "⋌": "⋌", "⋊": "⋊", "▹": "▹", "⊵": "⊵", "▸": "▸", "⧎": "⧎", "⥨": "⥨", "℞": "℞", "ś": "ś", "‚": "‚", "≻": "≻", "⪴": "⪴", "⪸": "⪸", "š": "š", "≽": "≽", "⪰": "⪰", "ş": "ş", "ŝ": "ŝ", "⪶": "⪶", "⪺": "⪺", "⋩": "⋩", "⨓": "⨓", "≿": "≿", "с": "с", "⋅": "⋅", "⊡": "⊡", "⩦": "⩦", "⇘": "⇘", "⤥": "⤥", "↘": "↘", "↘": "↘", "§": "§", "§": "§", ";": ";", "⤩": "⤩", "∖": "∖", "∖": "∖", "✶": "✶", "𝔰": "𝔰", "⌢": "⌢", "♯": "♯", "щ": "щ", "ш": "ш", "∣": "∣", "∥": "∥", "­": "­", "­": "­", "σ": "σ", "ς": "ς", "ς": "ς", "∼": "∼", "⩪": "⩪", "≃": "≃", "≃": "≃", "⪞": "⪞", "⪠": "⪠", "⪝": "⪝", "⪟": "⪟", "≆": "≆", "⨤": "⨤", "⥲": "⥲", "←": "←", "∖": "∖", "⨳": "⨳", "⧤": "⧤", "∣": "∣", "⌣": "⌣", "⪪": "⪪", "⪬": "⪬", "⪬︀": "⪬︀", "ь": "ь", "/": "/", "⧄": "⧄", "⌿": "⌿", "𝕤": "𝕤", "♠": "♠", "♠": "♠", "∥": "∥", "⊓": "⊓", "⊓︀": "⊓︀", "⊔": "⊔", "⊔︀": "⊔︀", "⊏": "⊏", "⊑": "⊑", "⊏": "⊏", "⊑": "⊑", "⊐": "⊐", "⊒": "⊒", "⊐": "⊐", "⊒": "⊒", "□": "□", "□": "□", "▪": "▪", "▪": "▪", "→": "→", "𝓈": "𝓈", "∖": "∖", "⌣": "⌣", "⋆": "⋆", "☆": "☆", "★": "★", "ϵ": "ϵ", "ϕ": "ϕ", "¯": "¯", "⊂": "⊂", "⫅": "⫅", "⪽": "⪽", "⊆": "⊆", "⫃": "⫃", "⫁": "⫁", "⫋": "⫋", "⊊": "⊊", "⪿": "⪿", "⥹": "⥹", "⊂": "⊂", "⊆": "⊆", "⫅": "⫅", "⊊": "⊊", "⫋": "⫋", "⫇": "⫇", "⫕": "⫕", "⫓": "⫓", "≻": "≻", "⪸": "⪸", "≽": "≽", "⪰": "⪰", "⪺": "⪺", "⪶": "⪶", "⋩": "⋩", "≿": "≿", "∑": "∑", "♪": "♪", "¹": "¹", "¹": "¹", "²": "²", "²": "²", "³": "³", "³": "³", "⊃": "⊃", "⫆": "⫆", "⪾": "⪾", "⫘": "⫘", "⊇": "⊇", "⫄": "⫄", "⟉": "⟉", "⫗": "⫗", "⥻": "⥻", "⫂": "⫂", "⫌": "⫌", "⊋": "⊋", "⫀": "⫀", "⊃": "⊃", "⊇": "⊇", "⫆": "⫆", "⊋": "⊋", "⫌": "⫌", "⫈": "⫈", "⫔": "⫔", "⫖": "⫖", "⇙": "⇙", "⤦": "⤦", "↙": "↙", "↙": "↙", "⤪": "⤪", "ß": "ß", "ß": "ß", "⌖": "⌖", "τ": "τ", "⎴": "⎴", "ť": "ť", "ţ": "ţ", "т": "т", "⃛": "⃛", "⌕": "⌕", "𝔱": "𝔱", "∴": "∴", "∴": "∴", "θ": "θ", "ϑ": "ϑ", "ϑ": "ϑ", "≈": "≈", "∼": "∼", " ": " ", "≈": "≈", "∼": "∼", "þ": "þ", "þ": "þ", "˜": "˜", "×": "×", "×": "×", "⊠": "⊠", "⨱": "⨱", "⨰": "⨰", "∭": "∭", "⤨": "⤨", "⊤": "⊤", "⌶": "⌶", "⫱": "⫱", "𝕥": "𝕥", "⫚": "⫚", "⤩": "⤩", "‴": "‴", "™": "™", "▵": "▵", "▿": "▿", "◃": "◃", "⊴": "⊴", "≜": "≜", "▹": "▹", "⊵": "⊵", "◬": "◬", "≜": "≜", "⨺": "⨺", "⨹": "⨹", "⧍": "⧍", "⨻": "⨻", "⏢": "⏢", "𝓉": "𝓉", "ц": "ц", "ћ": "ћ", "ŧ": "ŧ", "≬": "≬", "↞": "↞", "↠": "↠", "⇑": "⇑", "⥣": "⥣", "ú": "ú", "ú": "ú", "↑": "↑", "ў": "ў", "ŭ": "ŭ", "û": "û", "û": "û", "у": "у", "⇅": "⇅", "ű": "ű", "⥮": "⥮", "⥾": "⥾", "𝔲": "𝔲", "ù": "ù", "ù": "ù", "↿": "↿", "↾": "↾", "▀": "▀", "⌜": "⌜", "⌜": "⌜", "⌏": "⌏", "◸": "◸", "ū": "ū", "¨": "¨", "¨": "¨", "ų": "ų", "𝕦": "𝕦", "↑": "↑", "↕": "↕", "↿": "↿", "↾": "↾", "⊎": "⊎", "υ": "υ", "ϒ": "ϒ", "υ": "υ", "⇈": "⇈", "⌝": "⌝", "⌝": "⌝", "⌎": "⌎", "ů": "ů", "◹": "◹", "𝓊": "𝓊", "⋰": "⋰", "ũ": "ũ", "▵": "▵", "▴": "▴", "⇈": "⇈", "ü": "ü", "ü": "ü", "⦧": "⦧", "⇕": "⇕", "⫨": "⫨", "⫩": "⫩", "⊨": "⊨", "⦜": "⦜", "ϵ": "ϵ", "ϰ": "ϰ", "∅": "∅", "ϕ": "ϕ", "ϖ": "ϖ", "∝": "∝", "↕": "↕", "ϱ": "ϱ", "ς": "ς", "⊊︀": "⊊︀", "⫋︀": "⫋︀", "⊋︀": "⊋︀", "⫌︀": "⫌︀", "ϑ": "ϑ", "⊲": "⊲", "⊳": "⊳", "в": "в", "⊢": "⊢", "∨": "∨", "⊻": "⊻", "≚": "≚", "⋮": "⋮", "|": "|", "|": "|", "𝔳": "𝔳", "⊲": "⊲", "⊂⃒": "⊂⃒", "⊃⃒": "⊃⃒", "𝕧": "𝕧", "∝": "∝", "⊳": "⊳", "𝓋": "𝓋", "⫋︀": "⫋︀", "⊊︀": "⊊︀", "⫌︀": "⫌︀", "⊋︀": "⊋︀", "⦚": "⦚", "ŵ": "ŵ", "⩟": "⩟", "∧": "∧", "≙": "≙", "℘": "℘", "𝔴": "𝔴", "𝕨": "𝕨", "℘": "℘", "≀": "≀", "≀": "≀", "𝓌": "𝓌", "⋂": "⋂", "◯": "◯", "⋃": "⋃", "▽": "▽", "𝔵": "𝔵", "⟺": "⟺", "⟷": "⟷", "ξ": "ξ", "⟸": "⟸", "⟵": "⟵", "⟼": "⟼", "⋻": "⋻", "⨀": "⨀", "𝕩": "𝕩", "⨁": "⨁", "⨂": "⨂", "⟹": "⟹", "⟶": "⟶", "𝓍": "𝓍", "⨆": "⨆", "⨄": "⨄", "△": "△", "⋁": "⋁", "⋀": "⋀", "ý": "ý", "ý": "ý", "я": "я", "ŷ": "ŷ", "ы": "ы", "¥": "¥", "¥": "¥", "𝔶": "𝔶", "ї": "ї", "𝕪": "𝕪", "𝓎": "𝓎", "ю": "ю", "ÿ": "ÿ", "ÿ": "ÿ", "ź": "ź", "ž": "ž", "з": "з", "ż": "ż", "ℨ": "ℨ", "ζ": "ζ", "𝔷": "𝔷", "ж": "ж", "⇝": "⇝", "𝕫": "𝕫", "𝓏": "𝓏", "‍": "‍", "‌": "‌" }, characters: { "Æ": "Æ", "&": "&", "Á": "Á", "Ă": "Ă", "Â": "Â", "А": "А", "𝔄": "𝔄", "À": "À", "Α": "Α", "Ā": "Ā", "⩓": "⩓", "Ą": "Ą", "𝔸": "𝔸", "⁡": "⁡", "Å": "Å", "𝒜": "𝒜", "≔": "≔", "Ã": "Ã", "Ä": "Ä", "∖": "∖", "⫧": "⫧", "⌆": "⌆", "Б": "Б", "∵": "∵", "ℬ": "ℬ", "Β": "Β", "𝔅": "𝔅", "𝔹": "𝔹", "˘": "˘", "≎": "≎", "Ч": "Ч", "©": "©", "Ć": "Ć", "⋒": "⋒", "ⅅ": "ⅅ", "ℭ": "ℭ", "Č": "Č", "Ç": "Ç", "Ĉ": "Ĉ", "∰": "∰", "Ċ": "Ċ", "¸": "¸", "·": "·", "Χ": "Χ", "⊙": "⊙", "⊖": "⊖", "⊕": "⊕", "⊗": "⊗", "∲": "∲", "”": "”", "’": "’", "∷": "∷", "⩴": "⩴", "≡": "≡", "∯": "∯", "∮": "∮", "ℂ": "ℂ", "∐": "∐", "∳": "∳", "⨯": "⨯", "𝒞": "𝒞", "⋓": "⋓", "≍": "≍", "⤑": "⤑", "Ђ": "Ђ", "Ѕ": "Ѕ", "Џ": "Џ", "‡": "‡", "↡": "↡", "⫤": "⫤", "Ď": "Ď", "Д": "Д", "∇": "∇", "Δ": "Δ", "𝔇": "𝔇", "´": "´", "˙": "˙", "˝": "˝", "`": "`", "˜": "˜", "⋄": "⋄", "ⅆ": "ⅆ", "𝔻": "𝔻", "¨": "¨", "⃜": "⃜", "≐": "≐", "⇓": "⇓", "⇐": "⇐", "⇔": "⇔", "⟸": "⟸", "⟺": "⟺", "⟹": "⟹", "⇒": "⇒", "⊨": "⊨", "⇑": "⇑", "⇕": "⇕", "∥": "∥", "↓": "↓", "⤓": "⤓", "⇵": "⇵", "̑": "̑", "⥐": "⥐", "⥞": "⥞", "↽": "↽", "⥖": "⥖", "⥟": "⥟", "⇁": "⇁", "⥗": "⥗", "⊤": "⊤", "↧": "↧", "𝒟": "𝒟", "Đ": "Đ", "Ŋ": "Ŋ", "Ð": "Ð", "É": "É", "Ě": "Ě", "Ê": "Ê", "Э": "Э", "Ė": "Ė", "𝔈": "𝔈", "È": "È", "∈": "∈", "Ē": "Ē", "◻": "◻", "▫": "▫", "Ę": "Ę", "𝔼": "𝔼", "Ε": "Ε", "⩵": "⩵", "≂": "≂", "⇌": "⇌", "ℰ": "ℰ", "⩳": "⩳", "Η": "Η", "Ë": "Ë", "∃": "∃", "ⅇ": "ⅇ", "Ф": "Ф", "𝔉": "𝔉", "◼": "◼", "▪": "▪", "𝔽": "𝔽", "∀": "∀", "ℱ": "ℱ", "Ѓ": "Ѓ", ">": ">", "Γ": "Γ", "Ϝ": "Ϝ", "Ğ": "Ğ", "Ģ": "Ģ", "Ĝ": "Ĝ", "Г": "Г", "Ġ": "Ġ", "𝔊": "𝔊", "⋙": "⋙", "𝔾": "𝔾", "≥": "≥", "⋛": "⋛", "≧": "≧", "⪢": "⪢", "≷": "≷", "⩾": "⩾", "≳": "≳", "𝒢": "𝒢", "≫": "≫", "Ъ": "Ъ", "ˇ": "ˇ", "^": "^", "Ĥ": "Ĥ", "ℌ": "ℌ", "ℋ": "ℋ", "ℍ": "ℍ", "─": "─", "Ħ": "Ħ", "≏": "≏", "Е": "Е", "IJ": "IJ", "Ё": "Ё", "Í": "Í", "Î": "Î", "И": "И", "İ": "İ", "ℑ": "ℑ", "Ì": "Ì", "Ī": "Ī", "ⅈ": "ⅈ", "∬": "∬", "∫": "∫", "⋂": "⋂", "⁣": "⁣", "⁢": "⁢", "Į": "Į", "𝕀": "𝕀", "Ι": "Ι", "ℐ": "ℐ", "Ĩ": "Ĩ", "І": "І", "Ï": "Ï", "Ĵ": "Ĵ", "Й": "Й", "𝔍": "𝔍", "𝕁": "𝕁", "𝒥": "𝒥", "Ј": "Ј", "Є": "Є", "Х": "Х", "Ќ": "Ќ", "Κ": "Κ", "Ķ": "Ķ", "К": "К", "𝔎": "𝔎", "𝕂": "𝕂", "𝒦": "𝒦", "Љ": "Љ", "<": "<", "Ĺ": "Ĺ", "Λ": "Λ", "⟪": "⟪", "ℒ": "ℒ", "↞": "↞", "Ľ": "Ľ", "Ļ": "Ļ", "Л": "Л", "⟨": "⟨", "←": "←", "⇤": "⇤", "⇆": "⇆", "⌈": "⌈", "⟦": "⟦", "⥡": "⥡", "⇃": "⇃", "⥙": "⥙", "⌊": "⌊", "↔": "↔", "⥎": "⥎", "⊣": "⊣", "↤": "↤", "⥚": "⥚", "⊲": "⊲", "⧏": "⧏", "⊴": "⊴", "⥑": "⥑", "⥠": "⥠", "↿": "↿", "⥘": "⥘", "↼": "↼", "⥒": "⥒", "⋚": "⋚", "≦": "≦", "≶": "≶", "⪡": "⪡", "⩽": "⩽", "≲": "≲", "𝔏": "𝔏", "⋘": "⋘", "⇚": "⇚", "Ŀ": "Ŀ", "⟵": "⟵", "⟷": "⟷", "⟶": "⟶", "𝕃": "𝕃", "↙": "↙", "↘": "↘", "↰": "↰", "Ł": "Ł", "≪": "≪", "⤅": "⤅", "М": "М", " ": " ", "ℳ": "ℳ", "𝔐": "𝔐", "∓": "∓", "𝕄": "𝕄", "Μ": "Μ", "Њ": "Њ", "Ń": "Ń", "Ň": "Ň", "Ņ": "Ņ", "Н": "Н", "​": "​", "\n": " ", "𝔑": "𝔑", "⁠": "⁠", " ": " ", "ℕ": "ℕ", "⫬": "⫬", "≢": "≢", "≭": "≭", "∦": "∦", "∉": "∉", "≠": "≠", "≂̸": "≂̸", "∄": "∄", "≯": "≯", "≱": "≱", "≧̸": "≧̸", "≫̸": "≫̸", "≹": "≹", "⩾̸": "⩾̸", "≵": "≵", "≎̸": "≎̸", "≏̸": "≏̸", "⋪": "⋪", "⧏̸": "⧏̸", "⋬": "⋬", "≮": "≮", "≰": "≰", "≸": "≸", "≪̸": "≪̸", "⩽̸": "⩽̸", "≴": "≴", "⪢̸": "⪢̸", "⪡̸": "⪡̸", "⊀": "⊀", "⪯̸": "⪯̸", "⋠": "⋠", "∌": "∌", "⋫": "⋫", "⧐̸": "⧐̸", "⋭": "⋭", "⊏̸": "⊏̸", "⋢": "⋢", "⊐̸": "⊐̸", "⋣": "⋣", "⊂⃒": "⊂⃒", "⊈": "⊈", "⊁": "⊁", "⪰̸": "⪰̸", "⋡": "⋡", "≿̸": "≿̸", "⊃⃒": "⊃⃒", "⊉": "⊉", "≁": "≁", "≄": "≄", "≇": "≇", "≉": "≉", "∤": "∤", "𝒩": "𝒩", "Ñ": "Ñ", "Ν": "Ν", "Œ": "Œ", "Ó": "Ó", "Ô": "Ô", "О": "О", "Ő": "Ő", "𝔒": "𝔒", "Ò": "Ò", "Ō": "Ō", "Ω": "Ω", "Ο": "Ο", "𝕆": "𝕆", "“": "“", "‘": "‘", "⩔": "⩔", "𝒪": "𝒪", "Ø": "Ø", "Õ": "Õ", "⨷": "⨷", "Ö": "Ö", "‾": "‾", "⏞": "⏞", "⎴": "⎴", "⏜": "⏜", "∂": "∂", "П": "П", "𝔓": "𝔓", "Φ": "Φ", "Π": "Π", "±": "±", "ℙ": "ℙ", "⪻": "⪻", "≺": "≺", "⪯": "⪯", "≼": "≼", "≾": "≾", "″": "″", "∏": "∏", "∝": "∝", "𝒫": "𝒫", "Ψ": "Ψ", '"': """, "𝔔": "𝔔", "ℚ": "ℚ", "𝒬": "𝒬", "⤐": "⤐", "®": "®", "Ŕ": "Ŕ", "⟫": "⟫", "↠": "↠", "⤖": "⤖", "Ř": "Ř", "Ŗ": "Ŗ", "Р": "Р", "ℜ": "ℜ", "∋": "∋", "⇋": "⇋", "⥯": "⥯", "Ρ": "Ρ", "⟩": "⟩", "→": "→", "⇥": "⇥", "⇄": "⇄", "⌉": "⌉", "⟧": "⟧", "⥝": "⥝", "⇂": "⇂", "⥕": "⥕", "⌋": "⌋", "⊢": "⊢", "↦": "↦", "⥛": "⥛", "⊳": "⊳", "⧐": "⧐", "⊵": "⊵", "⥏": "⥏", "⥜": "⥜", "↾": "↾", "⥔": "⥔", "⇀": "⇀", "⥓": "⥓", "ℝ": "ℝ", "⥰": "⥰", "⇛": "⇛", "ℛ": "ℛ", "↱": "↱", "⧴": "⧴", "Щ": "Щ", "Ш": "Ш", "Ь": "Ь", "Ś": "Ś", "⪼": "⪼", "Š": "Š", "Ş": "Ş", "Ŝ": "Ŝ", "С": "С", "𝔖": "𝔖", "↑": "↑", "Σ": "Σ", "∘": "∘", "𝕊": "𝕊", "√": "√", "□": "□", "⊓": "⊓", "⊏": "⊏", "⊑": "⊑", "⊐": "⊐", "⊒": "⊒", "⊔": "⊔", "𝒮": "𝒮", "⋆": "⋆", "⋐": "⋐", "⊆": "⊆", "≻": "≻", "⪰": "⪰", "≽": "≽", "≿": "≿", "∑": "∑", "⋑": "⋑", "⊃": "⊃", "⊇": "⊇", "Þ": "Þ", "™": "™", "Ћ": "Ћ", "Ц": "Ц", " ": " ", "Τ": "Τ", "Ť": "Ť", "Ţ": "Ţ", "Т": "Т", "𝔗": "𝔗", "∴": "∴", "Θ": "Θ", "  ": "  ", " ": " ", "∼": "∼", "≃": "≃", "≅": "≅", "≈": "≈", "𝕋": "𝕋", "⃛": "⃛", "𝒯": "𝒯", "Ŧ": "Ŧ", "Ú": "Ú", "↟": "↟", "⥉": "⥉", "Ў": "Ў", "Ŭ": "Ŭ", "Û": "Û", "У": "У", "Ű": "Ű", "𝔘": "𝔘", "Ù": "Ù", "Ū": "Ū", _: "_", "⏟": "⏟", "⎵": "⎵", "⏝": "⏝", "⋃": "⋃", "⊎": "⊎", "Ų": "Ų", "𝕌": "𝕌", "⤒": "⤒", "⇅": "⇅", "↕": "↕", "⥮": "⥮", "⊥": "⊥", "↥": "↥", "↖": "↖", "↗": "↗", "ϒ": "ϒ", "Υ": "Υ", "Ů": "Ů", "𝒰": "𝒰", "Ũ": "Ũ", "Ü": "Ü", "⊫": "⊫", "⫫": "⫫", "В": "В", "⊩": "⊩", "⫦": "⫦", "⋁": "⋁", "‖": "‖", "∣": "∣", "|": "|", "❘": "❘", "≀": "≀", " ": " ", "𝔙": "𝔙", "𝕍": "𝕍", "𝒱": "𝒱", "⊪": "⊪", "Ŵ": "Ŵ", "⋀": "⋀", "𝔚": "𝔚", "𝕎": "𝕎", "𝒲": "𝒲", "𝔛": "𝔛", "Ξ": "Ξ", "𝕏": "𝕏", "𝒳": "𝒳", "Я": "Я", "Ї": "Ї", "Ю": "Ю", "Ý": "Ý", "Ŷ": "Ŷ", "Ы": "Ы", "𝔜": "𝔜", "𝕐": "𝕐", "𝒴": "𝒴", "Ÿ": "Ÿ", "Ж": "Ж", "Ź": "Ź", "Ž": "Ž", "З": "З", "Ż": "Ż", "Ζ": "Ζ", "ℨ": "ℨ", "ℤ": "ℤ", "𝒵": "𝒵", "á": "á", "ă": "ă", "∾": "∾", "∾̳": "∾̳", "∿": "∿", "â": "â", "а": "а", "æ": "æ", "𝔞": "𝔞", "à": "à", "ℵ": "ℵ", "α": "α", "ā": "ā", "⨿": "⨿", "∧": "∧", "⩕": "⩕", "⩜": "⩜", "⩘": "⩘", "⩚": "⩚", "∠": "∠", "⦤": "⦤", "∡": "∡", "⦨": "⦨", "⦩": "⦩", "⦪": "⦪", "⦫": "⦫", "⦬": "⦬", "⦭": "⦭", "⦮": "⦮", "⦯": "⦯", "∟": "∟", "⊾": "⊾", "⦝": "⦝", "∢": "∢", "⍼": "⍼", "ą": "ą", "𝕒": "𝕒", "⩰": "⩰", "⩯": "⩯", "≊": "≊", "≋": "≋", "'": "'", "å": "å", "𝒶": "𝒶", "*": "*", "ã": "ã", "ä": "ä", "⨑": "⨑", "⫭": "⫭", "≌": "≌", "϶": "϶", "‵": "‵", "∽": "∽", "⋍": "⋍", "⊽": "⊽", "⌅": "⌅", "⎶": "⎶", "б": "б", "„": "„", "⦰": "⦰", "β": "β", "ℶ": "ℶ", "≬": "≬", "𝔟": "𝔟", "◯": "◯", "⨀": "⨀", "⨁": "⨁", "⨂": "⨂", "⨆": "⨆", "★": "★", "▽": "▽", "△": "△", "⨄": "⨄", "⤍": "⤍", "⧫": "⧫", "▴": "▴", "▾": "▾", "◂": "◂", "▸": "▸", "␣": "␣", "▒": "▒", "░": "░", "▓": "▓", "█": "█", "=⃥": "=⃥", "≡⃥": "≡⃥", "⌐": "⌐", "𝕓": "𝕓", "⋈": "⋈", "╗": "╗", "╔": "╔", "╖": "╖", "╓": "╓", "═": "═", "╦": "╦", "╩": "╩", "╤": "╤", "╧": "╧", "╝": "╝", "╚": "╚", "╜": "╜", "╙": "╙", "║": "║", "╬": "╬", "╣": "╣", "╠": "╠", "╫": "╫", "╢": "╢", "╟": "╟", "⧉": "⧉", "╕": "╕", "╒": "╒", "┐": "┐", "┌": "┌", "╥": "╥", "╨": "╨", "┬": "┬", "┴": "┴", "⊟": "⊟", "⊞": "⊞", "⊠": "⊠", "╛": "╛", "╘": "╘", "┘": "┘", "└": "└", "│": "│", "╪": "╪", "╡": "╡", "╞": "╞", "┼": "┼", "┤": "┤", "├": "├", "¦": "¦", "𝒷": "𝒷", "⁏": "⁏", "\\": "\", "⧅": "⧅", "⟈": "⟈", "•": "•", "⪮": "⪮", "ć": "ć", "∩": "∩", "⩄": "⩄", "⩉": "⩉", "⩋": "⩋", "⩇": "⩇", "⩀": "⩀", "∩︀": "∩︀", "⁁": "⁁", "⩍": "⩍", "č": "č", "ç": "ç", "ĉ": "ĉ", "⩌": "⩌", "⩐": "⩐", "ċ": "ċ", "⦲": "⦲", "¢": "¢", "𝔠": "𝔠", "ч": "ч", "✓": "✓", "χ": "χ", "○": "○", "⧃": "⧃", "ˆ": "ˆ", "≗": "≗", "↺": "↺", "↻": "↻", "Ⓢ": "Ⓢ", "⊛": "⊛", "⊚": "⊚", "⊝": "⊝", "⨐": "⨐", "⫯": "⫯", "⧂": "⧂", "♣": "♣", ":": ":", ",": ",", "@": "@", "∁": "∁", "⩭": "⩭", "𝕔": "𝕔", "℗": "℗", "↵": "↵", "✗": "✗", "𝒸": "𝒸", "⫏": "⫏", "⫑": "⫑", "⫐": "⫐", "⫒": "⫒", "⋯": "⋯", "⤸": "⤸", "⤵": "⤵", "⋞": "⋞", "⋟": "⋟", "↶": "↶", "⤽": "⤽", "∪": "∪", "⩈": "⩈", "⩆": "⩆", "⩊": "⩊", "⊍": "⊍", "⩅": "⩅", "∪︀": "∪︀", "↷": "↷", "⤼": "⤼", "⋎": "⋎", "⋏": "⋏", "¤": "¤", "∱": "∱", "⌭": "⌭", "⥥": "⥥", "†": "†", "ℸ": "ℸ", "‐": "‐", "⤏": "⤏", "ď": "ď", "д": "д", "⇊": "⇊", "⩷": "⩷", "°": "°", "δ": "δ", "⦱": "⦱", "⥿": "⥿", "𝔡": "𝔡", "♦": "♦", "ϝ": "ϝ", "⋲": "⋲", "÷": "÷", "⋇": "⋇", "ђ": "ђ", "⌞": "⌞", "⌍": "⌍", $: "$", "𝕕": "𝕕", "≑": "≑", "∸": "∸", "∔": "∔", "⊡": "⊡", "⌟": "⌟", "⌌": "⌌", "𝒹": "𝒹", "ѕ": "ѕ", "⧶": "⧶", "đ": "đ", "⋱": "⋱", "▿": "▿", "⦦": "⦦", "џ": "џ", "⟿": "⟿", "é": "é", "⩮": "⩮", "ě": "ě", "≖": "≖", "ê": "ê", "≕": "≕", "э": "э", "ė": "ė", "≒": "≒", "𝔢": "𝔢", "⪚": "⪚", "è": "è", "⪖": "⪖", "⪘": "⪘", "⪙": "⪙", "⏧": "⏧", "ℓ": "ℓ", "⪕": "⪕", "⪗": "⪗", "ē": "ē", "∅": "∅", " ": " ", " ": " ", " ": " ", "ŋ": "ŋ", " ": " ", "ę": "ę", "𝕖": "𝕖", "⋕": "⋕", "⧣": "⧣", "⩱": "⩱", "ε": "ε", "ϵ": "ϵ", "=": "=", "≟": "≟", "⩸": "⩸", "⧥": "⧥", "≓": "≓", "⥱": "⥱", "ℯ": "ℯ", "η": "η", "ð": "ð", "ë": "ë", "€": "€", "!": "!", "ф": "ф", "♀": "♀", "ffi": "ffi", "ff": "ff", "ffl": "ffl", "𝔣": "𝔣", "fi": "fi", fj: "fj", "♭": "♭", "fl": "fl", "▱": "▱", "ƒ": "ƒ", "𝕗": "𝕗", "⋔": "⋔", "⫙": "⫙", "⨍": "⨍", "½": "½", "⅓": "⅓", "¼": "¼", "⅕": "⅕", "⅙": "⅙", "⅛": "⅛", "⅔": "⅔", "⅖": "⅖", "¾": "¾", "⅗": "⅗", "⅜": "⅜", "⅘": "⅘", "⅚": "⅚", "⅝": "⅝", "⅞": "⅞", "⁄": "⁄", "⌢": "⌢", "𝒻": "𝒻", "⪌": "⪌", "ǵ": "ǵ", "γ": "γ", "⪆": "⪆", "ğ": "ğ", "ĝ": "ĝ", "г": "г", "ġ": "ġ", "⪩": "⪩", "⪀": "⪀", "⪂": "⪂", "⪄": "⪄", "⋛︀": "⋛︀", "⪔": "⪔", "𝔤": "𝔤", "ℷ": "ℷ", "ѓ": "ѓ", "⪒": "⪒", "⪥": "⪥", "⪤": "⪤", "≩": "≩", "⪊": "⪊", "⪈": "⪈", "⋧": "⋧", "𝕘": "𝕘", "ℊ": "ℊ", "⪎": "⪎", "⪐": "⪐", "⪧": "⪧", "⩺": "⩺", "⋗": "⋗", "⦕": "⦕", "⩼": "⩼", "⥸": "⥸", "≩︀": "≩︀", "ъ": "ъ", "⥈": "⥈", "↭": "↭", "ℏ": "ℏ", "ĥ": "ĥ", "♥": "♥", "…": "…", "⊹": "⊹", "𝔥": "𝔥", "⤥": "⤥", "⤦": "⤦", "⇿": "⇿", "∻": "∻", "↩": "↩", "↪": "↪", "𝕙": "𝕙", "―": "―", "𝒽": "𝒽", "ħ": "ħ", "⁃": "⁃", "í": "í", "î": "î", "и": "и", "е": "е", "¡": "¡", "𝔦": "𝔦", "ì": "ì", "⨌": "⨌", "∭": "∭", "⧜": "⧜", "℩": "℩", "ij": "ij", "ī": "ī", "ı": "ı", "⊷": "⊷", "Ƶ": "Ƶ", "℅": "℅", "∞": "∞", "⧝": "⧝", "⊺": "⊺", "⨗": "⨗", "⨼": "⨼", "ё": "ё", "į": "į", "𝕚": "𝕚", "ι": "ι", "¿": "¿", "𝒾": "𝒾", "⋹": "⋹", "⋵": "⋵", "⋴": "⋴", "⋳": "⋳", "ĩ": "ĩ", "і": "і", "ï": "ï", "ĵ": "ĵ", "й": "й", "𝔧": "𝔧", "ȷ": "ȷ", "𝕛": "𝕛", "𝒿": "𝒿", "ј": "ј", "є": "є", "κ": "κ", "ϰ": "ϰ", "ķ": "ķ", "к": "к", "𝔨": "𝔨", "ĸ": "ĸ", "х": "х", "ќ": "ќ", "𝕜": "𝕜", "𝓀": "𝓀", "⤛": "⤛", "⤎": "⤎", "⪋": "⪋", "⥢": "⥢", "ĺ": "ĺ", "⦴": "⦴", "λ": "λ", "⦑": "⦑", "⪅": "⪅", "«": "«", "⤟": "⤟", "⤝": "⤝", "↫": "↫", "⤹": "⤹", "⥳": "⥳", "↢": "↢", "⪫": "⪫", "⤙": "⤙", "⪭": "⪭", "⪭︀": "⪭︀", "⤌": "⤌", "❲": "❲", "{": "{", "[": "[", "⦋": "⦋", "⦏": "⦏", "⦍": "⦍", "ľ": "ľ", "ļ": "ļ", "л": "л", "⤶": "⤶", "⥧": "⥧", "⥋": "⥋", "↲": "↲", "≤": "≤", "⇇": "⇇", "⋋": "⋋", "⪨": "⪨", "⩿": "⩿", "⪁": "⪁", "⪃": "⪃", "⋚︀": "⋚︀", "⪓": "⪓", "⋖": "⋖", "⥼": "⥼", "𝔩": "𝔩", "⪑": "⪑", "⥪": "⥪", "▄": "▄", "љ": "љ", "⥫": "⥫", "◺": "◺", "ŀ": "ŀ", "⎰": "⎰", "≨": "≨", "⪉": "⪉", "⪇": "⪇", "⋦": "⋦", "⟬": "⟬", "⇽": "⇽", "⟼": "⟼", "↬": "↬", "⦅": "⦅", "𝕝": "𝕝", "⨭": "⨭", "⨴": "⨴", "∗": "∗", "◊": "◊", "(": "(", "⦓": "⦓", "⥭": "⥭", "‎": "‎", "⊿": "⊿", "‹": "‹", "𝓁": "𝓁", "⪍": "⪍", "⪏": "⪏", "‚": "‚", "ł": "ł", "⪦": "⪦", "⩹": "⩹", "⋉": "⋉", "⥶": "⥶", "⩻": "⩻", "⦖": "⦖", "◃": "◃", "⥊": "⥊", "⥦": "⥦", "≨︀": "≨︀", "∺": "∺", "¯": "¯", "♂": "♂", "✠": "✠", "▮": "▮", "⨩": "⨩", "м": "м", "—": "—", "𝔪": "𝔪", "℧": "℧", "µ": "µ", "⫰": "⫰", "−": "−", "⨪": "⨪", "⫛": "⫛", "⊧": "⊧", "𝕞": "𝕞", "𝓂": "𝓂", "μ": "μ", "⊸": "⊸", "⋙̸": "⋙̸", "≫⃒": "≫⃒", "⇍": "⇍", "⇎": "⇎", "⋘̸": "⋘̸", "≪⃒": "≪⃒", "⇏": "⇏", "⊯": "⊯", "⊮": "⊮", "ń": "ń", "∠⃒": "∠⃒", "⩰̸": "⩰̸", "≋̸": "≋̸", "ʼn": "ʼn", "♮": "♮", "⩃": "⩃", "ň": "ň", "ņ": "ņ", "⩭̸": "⩭̸", "⩂": "⩂", "н": "н", "–": "–", "⇗": "⇗", "⤤": "⤤", "≐̸": "≐̸", "⤨": "⤨", "𝔫": "𝔫", "↮": "↮", "⫲": "⫲", "⋼": "⋼", "⋺": "⋺", "њ": "њ", "≦̸": "≦̸", "↚": "↚", "‥": "‥", "𝕟": "𝕟", "¬": "¬", "⋹̸": "⋹̸", "⋵̸": "⋵̸", "⋷": "⋷", "⋶": "⋶", "⋾": "⋾", "⋽": "⋽", "⫽⃥": "⫽⃥", "∂̸": "∂̸", "⨔": "⨔", "↛": "↛", "⤳̸": "⤳̸", "↝̸": "↝̸", "𝓃": "𝓃", "⊄": "⊄", "⫅̸": "⫅̸", "⊅": "⊅", "⫆̸": "⫆̸", "ñ": "ñ", "ν": "ν", "#": "#", "№": "№", " ": " ", "⊭": "⊭", "⤄": "⤄", "≍⃒": "≍⃒", "⊬": "⊬", "≥⃒": "≥⃒", ">⃒": ">⃒", "⧞": "⧞", "⤂": "⤂", "≤⃒": "≤⃒", "<⃒": "<⃒", "⊴⃒": "⊴⃒", "⤃": "⤃", "⊵⃒": "⊵⃒", "∼⃒": "∼⃒", "⇖": "⇖", "⤣": "⤣", "⤧": "⤧", "ó": "ó", "ô": "ô", "о": "о", "ő": "ő", "⨸": "⨸", "⦼": "⦼", "œ": "œ", "⦿": "⦿", "𝔬": "𝔬", "˛": "˛", "ò": "ò", "⧁": "⧁", "⦵": "⦵", "⦾": "⦾", "⦻": "⦻", "⧀": "⧀", "ō": "ō", "ω": "ω", "ο": "ο", "⦶": "⦶", "𝕠": "𝕠", "⦷": "⦷", "⦹": "⦹", "∨": "∨", "⩝": "⩝", "ℴ": "ℴ", "ª": "ª", "º": "º", "⊶": "⊶", "⩖": "⩖", "⩗": "⩗", "⩛": "⩛", "ø": "ø", "⊘": "⊘", "õ": "õ", "⨶": "⨶", "ö": "ö", "⌽": "⌽", "¶": "¶", "⫳": "⫳", "⫽": "⫽", "п": "п", "%": "%", ".": ".", "‰": "‰", "‱": "‱", "𝔭": "𝔭", "φ": "φ", "ϕ": "ϕ", "☎": "☎", "π": "π", "ϖ": "ϖ", "ℎ": "ℎ", "+": "+", "⨣": "⨣", "⨢": "⨢", "⨥": "⨥", "⩲": "⩲", "⨦": "⨦", "⨧": "⨧", "⨕": "⨕", "𝕡": "𝕡", "£": "£", "⪳": "⪳", "⪷": "⪷", "⪹": "⪹", "⪵": "⪵", "⋨": "⋨", "′": "′", "⌮": "⌮", "⌒": "⌒", "⌓": "⌓", "⊰": "⊰", "𝓅": "𝓅", "ψ": "ψ", " ": " ", "𝔮": "𝔮", "𝕢": "𝕢", "⁗": "⁗", "𝓆": "𝓆", "⨖": "⨖", "?": "?", "⤜": "⤜", "⥤": "⥤", "∽̱": "∽̱", "ŕ": "ŕ", "⦳": "⦳", "⦒": "⦒", "⦥": "⦥", "»": "»", "⥵": "⥵", "⤠": "⤠", "⤳": "⤳", "⤞": "⤞", "⥅": "⥅", "⥴": "⥴", "↣": "↣", "↝": "↝", "⤚": "⤚", "∶": "∶", "❳": "❳", "}": "}", "]": "]", "⦌": "⦌", "⦎": "⦎", "⦐": "⦐", "ř": "ř", "ŗ": "ŗ", "р": "р", "⤷": "⤷", "⥩": "⥩", "↳": "↳", "▭": "▭", "⥽": "⥽", "𝔯": "𝔯", "⥬": "⥬", "ρ": "ρ", "ϱ": "ϱ", "⇉": "⇉", "⋌": "⋌", "˚": "˚", "‏": "‏", "⎱": "⎱", "⫮": "⫮", "⟭": "⟭", "⇾": "⇾", "⦆": "⦆", "𝕣": "𝕣", "⨮": "⨮", "⨵": "⨵", ")": ")", "⦔": "⦔", "⨒": "⨒", "›": "›", "𝓇": "𝓇", "⋊": "⋊", "▹": "▹", "⧎": "⧎", "⥨": "⥨", "℞": "℞", "ś": "ś", "⪴": "⪴", "⪸": "⪸", "š": "š", "ş": "ş", "ŝ": "ŝ", "⪶": "⪶", "⪺": "⪺", "⋩": "⋩", "⨓": "⨓", "с": "с", "⋅": "⋅", "⩦": "⩦", "⇘": "⇘", "§": "§", ";": ";", "⤩": "⤩", "✶": "✶", "𝔰": "𝔰", "♯": "♯", "щ": "щ", "ш": "ш", "­": "­", "σ": "σ", "ς": "ς", "⩪": "⩪", "⪞": "⪞", "⪠": "⪠", "⪝": "⪝", "⪟": "⪟", "≆": "≆", "⨤": "⨤", "⥲": "⥲", "⨳": "⨳", "⧤": "⧤", "⌣": "⌣", "⪪": "⪪", "⪬": "⪬", "⪬︀": "⪬︀", "ь": "ь", "/": "/", "⧄": "⧄", "⌿": "⌿", "𝕤": "𝕤", "♠": "♠", "⊓︀": "⊓︀", "⊔︀": "⊔︀", "𝓈": "𝓈", "☆": "☆", "⊂": "⊂", "⫅": "⫅", "⪽": "⪽", "⫃": "⫃", "⫁": "⫁", "⫋": "⫋", "⊊": "⊊", "⪿": "⪿", "⥹": "⥹", "⫇": "⫇", "⫕": "⫕", "⫓": "⫓", "♪": "♪", "¹": "¹", "²": "²", "³": "³", "⫆": "⫆", "⪾": "⪾", "⫘": "⫘", "⫄": "⫄", "⟉": "⟉", "⫗": "⫗", "⥻": "⥻", "⫂": "⫂", "⫌": "⫌", "⊋": "⊋", "⫀": "⫀", "⫈": "⫈", "⫔": "⫔", "⫖": "⫖", "⇙": "⇙", "⤪": "⤪", "ß": "ß", "⌖": "⌖", "τ": "τ", "ť": "ť", "ţ": "ţ", "т": "т", "⌕": "⌕", "𝔱": "𝔱", "θ": "θ", "ϑ": "ϑ", "þ": "þ", "×": "×", "⨱": "⨱", "⨰": "⨰", "⌶": "⌶", "⫱": "⫱", "𝕥": "𝕥", "⫚": "⫚", "‴": "‴", "▵": "▵", "≜": "≜", "◬": "◬", "⨺": "⨺", "⨹": "⨹", "⧍": "⧍", "⨻": "⨻", "⏢": "⏢", "𝓉": "𝓉", "ц": "ц", "ћ": "ћ", "ŧ": "ŧ", "⥣": "⥣", "ú": "ú", "ў": "ў", "ŭ": "ŭ", "û": "û", "у": "у", "ű": "ű", "⥾": "⥾", "𝔲": "𝔲", "ù": "ù", "▀": "▀", "⌜": "⌜", "⌏": "⌏", "◸": "◸", "ū": "ū", "ų": "ų", "𝕦": "𝕦", "υ": "υ", "⇈": "⇈", "⌝": "⌝", "⌎": "⌎", "ů": "ů", "◹": "◹", "𝓊": "𝓊", "⋰": "⋰", "ũ": "ũ", "ü": "ü", "⦧": "⦧", "⫨": "⫨", "⫩": "⫩", "⦜": "⦜", "⊊︀": "⊊︀", "⫋︀": "⫋︀", "⊋︀": "⊋︀", "⫌︀": "⫌︀", "в": "в", "⊻": "⊻", "≚": "≚", "⋮": "⋮", "𝔳": "𝔳", "𝕧": "𝕧", "𝓋": "𝓋", "⦚": "⦚", "ŵ": "ŵ", "⩟": "⩟", "≙": "≙", "℘": "℘", "𝔴": "𝔴", "𝕨": "𝕨", "𝓌": "𝓌", "𝔵": "𝔵", "ξ": "ξ", "⋻": "⋻", "𝕩": "𝕩", "𝓍": "𝓍", "ý": "ý", "я": "я", "ŷ": "ŷ", "ы": "ы", "¥": "¥", "𝔶": "𝔶", "ї": "ї", "𝕪": "𝕪", "𝓎": "𝓎", "ю": "ю", "ÿ": "ÿ", "ź": "ź", "ž": "ž", "з": "з", "ż": "ż", "ζ": "ζ", "𝔷": "𝔷", "ж": "ж", "⇝": "⇝", "𝕫": "𝕫", "𝓏": "𝓏", "‍": "‍", "‌": "‌" } } }; + } }); -module.exports = __toCommonJS(main_exports); -var import_events = __toESM(require("events"), 1); -// src/utils/retrieve.js -var import_axios = __toESM(require_axios2(), 1); - -// src/config.js -var import_bellajs = __toESM(require_bella(), 1); -var requestOptions = { - headers: { - "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0", - "accept-encoding": "deflate,zlib,gzip" - }, - responseType: "text", - responseEncoding: "utf8", - timeout: 3e4, - maxRedirects: 5 -}; -var getRequestOptions = () => { - return (0, import_bellajs.clone)(requestOptions); -}; -var setRequestOptions = (opts) => { - (0, import_bellajs.copies)(opts, requestOptions); -}; - -// src/utils/retrieve.js -var retrieve_default = async (url) => { - const res = await import_axios.default.get(url, getRequestOptions()); - return res.data.trim(); -}; +// node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/numeric-unicode-map.js +var require_numeric_unicode_map = __commonJS({ + "node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/numeric-unicode-map.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.numericUnicodeMap = { 0: 65533, 128: 8364, 130: 8218, 131: 402, 132: 8222, 133: 8230, 134: 8224, 135: 8225, 136: 710, 137: 8240, 138: 352, 139: 8249, 140: 338, 142: 381, 145: 8216, 146: 8217, 147: 8220, 148: 8221, 149: 8226, 150: 8211, 151: 8212, 152: 732, 153: 8482, 154: 353, 155: 8250, 156: 339, 158: 382, 159: 376 }; + } +}); -// src/utils/parser.js -var import_html_entities = __toESM(require_lib(), 1); -var import_bellajs3 = __toESM(require_bella(), 1); - -// src/utils/validator.js -var import_bellajs2 = __toESM(require_bella(), 1); -var import_fast_xml_parser = __toESM(require_fxp(), 1); -var isRSS = (data = {}) => { - return (0, import_bellajs2.hasProperty)(data, "rss") && (0, import_bellajs2.hasProperty)(data.rss, "channel"); -}; -var isAtom = (data = {}) => { - return (0, import_bellajs2.hasProperty)(data, "feed") && (0, import_bellajs2.hasProperty)(data.feed, "entry"); -}; -var validate = (xml = "") => { - const result = import_fast_xml_parser.XMLValidator.validate(xml); - return result === true; -}; +// node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/surrogate-pairs.js +var require_surrogate_pairs = __commonJS({ + "node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/surrogate-pairs.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.fromCodePoint = String.fromCodePoint || function(astralCodePoint) { + return String.fromCharCode(Math.floor((astralCodePoint - 65536) / 1024) + 55296, (astralCodePoint - 65536) % 1024 + 56320); + }; + exports.getCodePoint = String.prototype.codePointAt ? function(input, position) { + return input.codePointAt(position); + } : function(input, position) { + return (input.charCodeAt(position) - 55296) * 1024 + input.charCodeAt(position + 1) - 56320 + 65536; + }; + exports.highSurrogateFrom = 55296; + exports.highSurrogateTo = 56319; + } +}); -// src/utils/xml2obj.js -var import_fxp = __toESM(require_fxp(), 1); +// node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/index.js +var require_lib = __commonJS({ + "node_modules/.pnpm/html-entities@2.3.3/node_modules/html-entities/lib/index.js"(exports) { + "use strict"; + var __assign = exports && exports.__assign || function() { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + var named_references_1 = require_named_references(); + var numeric_unicode_map_1 = require_numeric_unicode_map(); + var surrogate_pairs_1 = require_surrogate_pairs(); + var allNamedReferences = __assign(__assign({}, named_references_1.namedReferences), { all: named_references_1.namedReferences.html5 }); + var encodeRegExps = { + specialChars: /[<>'"&]/g, + nonAscii: /(?:[<>'"&\u0080-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g, + nonAsciiPrintable: /(?:[<>'"&\x01-\x08\x11-\x15\x17-\x1F\x7f-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g, + extensive: /(?:[\x01-\x0c\x0e-\x1f\x21-\x2c\x2e-\x2f\x3a-\x40\x5b-\x60\x7b-\x7d\x7f-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g + }; + var defaultEncodeOptions = { + mode: "specialChars", + level: "all", + numeric: "decimal" + }; + function encode(text, _a) { + var _b = _a === void 0 ? defaultEncodeOptions : _a, _c = _b.mode, mode = _c === void 0 ? "specialChars" : _c, _d = _b.numeric, numeric = _d === void 0 ? "decimal" : _d, _e = _b.level, level = _e === void 0 ? "all" : _e; + if (!text) { + return ""; + } + var encodeRegExp = encodeRegExps[mode]; + var references = allNamedReferences[level].characters; + var isHex = numeric === "hexadecimal"; + encodeRegExp.lastIndex = 0; + var _b = encodeRegExp.exec(text); + var _c; + if (_b) { + _c = ""; + var _d = 0; + do { + if (_d !== _b.index) { + _c += text.substring(_d, _b.index); + } + var _e = _b[0]; + var result_1 = references[_e]; + if (!result_1) { + var code_1 = _e.length > 1 ? surrogate_pairs_1.getCodePoint(_e, 0) : _e.charCodeAt(0); + result_1 = (isHex ? "&#x" + code_1.toString(16) : "&#" + code_1) + ";"; + } + _c += result_1; + _d = _b.index + _e.length; + } while (_b = encodeRegExp.exec(text)); + if (_d !== text.length) { + _c += text.substring(_d); + } + } else { + _c = text; + } + return _c; + } + exports.encode = encode; + var defaultDecodeOptions = { + scope: "body", + level: "all" + }; + var strict = /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);/g; + var attribute = /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+)[;=]?/g; + var baseDecodeRegExps = { + xml: { + strict, + attribute, + body: named_references_1.bodyRegExps.xml + }, + html4: { + strict, + attribute, + body: named_references_1.bodyRegExps.html4 + }, + html5: { + strict, + attribute, + body: named_references_1.bodyRegExps.html5 + } + }; + var decodeRegExps = __assign(__assign({}, baseDecodeRegExps), { all: baseDecodeRegExps.html5 }); + var fromCharCode = String.fromCharCode; + var outOfBoundsChar = fromCharCode(65533); + var defaultDecodeEntityOptions = { + level: "all" + }; + function decodeEntity(entity, _a) { + var _b = (_a === void 0 ? defaultDecodeEntityOptions : _a).level, level = _b === void 0 ? "all" : _b; + if (!entity) { + return ""; + } + var _b = entity; + var decodeEntityLastChar_1 = entity[entity.length - 1]; + if (false) { + _b = entity; + } else if (false) { + _b = entity; + } else { + var decodeResultByReference_1 = allNamedReferences[level].entities[entity]; + if (decodeResultByReference_1) { + _b = decodeResultByReference_1; + } else if (entity[0] === "&" && entity[1] === "#") { + var decodeSecondChar_1 = entity[2]; + var decodeCode_1 = decodeSecondChar_1 == "x" || decodeSecondChar_1 == "X" ? parseInt(entity.substr(3), 16) : parseInt(entity.substr(2)); + _b = decodeCode_1 >= 1114111 ? outOfBoundsChar : decodeCode_1 > 65535 ? surrogate_pairs_1.fromCodePoint(decodeCode_1) : fromCharCode(numeric_unicode_map_1.numericUnicodeMap[decodeCode_1] || decodeCode_1); + } + } + return _b; + } + exports.decodeEntity = decodeEntity; + function decode2(text, _a) { + var decodeSecondChar_1 = _a === void 0 ? defaultDecodeOptions : _a, decodeCode_1 = decodeSecondChar_1.level, level = decodeCode_1 === void 0 ? "all" : decodeCode_1, _b = decodeSecondChar_1.scope, scope = _b === void 0 ? level === "xml" ? "strict" : "body" : _b; + if (!text) { + return ""; + } + var decodeRegExp = decodeRegExps[level][scope]; + var references = allNamedReferences[level].entities; + var isAttribute = scope === "attribute"; + var isStrict = scope === "strict"; + decodeRegExp.lastIndex = 0; + var replaceMatch_1 = decodeRegExp.exec(text); + var replaceResult_1; + if (replaceMatch_1) { + replaceResult_1 = ""; + var replaceLastIndex_1 = 0; + do { + if (replaceLastIndex_1 !== replaceMatch_1.index) { + replaceResult_1 += text.substring(replaceLastIndex_1, replaceMatch_1.index); + } + var replaceInput_1 = replaceMatch_1[0]; + var decodeResult_1 = replaceInput_1; + var decodeEntityLastChar_2 = replaceInput_1[replaceInput_1.length - 1]; + if (isAttribute && decodeEntityLastChar_2 === "=") { + decodeResult_1 = replaceInput_1; + } else if (isStrict && decodeEntityLastChar_2 !== ";") { + decodeResult_1 = replaceInput_1; + } else { + var decodeResultByReference_2 = references[replaceInput_1]; + if (decodeResultByReference_2) { + decodeResult_1 = decodeResultByReference_2; + } else if (replaceInput_1[0] === "&" && replaceInput_1[1] === "#") { + var decodeSecondChar_2 = replaceInput_1[2]; + var decodeCode_2 = decodeSecondChar_2 == "x" || decodeSecondChar_2 == "X" ? parseInt(replaceInput_1.substr(3), 16) : parseInt(replaceInput_1.substr(2)); + decodeResult_1 = decodeCode_2 >= 1114111 ? outOfBoundsChar : decodeCode_2 > 65535 ? surrogate_pairs_1.fromCodePoint(decodeCode_2) : fromCharCode(numeric_unicode_map_1.numericUnicodeMap[decodeCode_2] || decodeCode_2); + } + } + replaceResult_1 += decodeResult_1; + replaceLastIndex_1 = replaceMatch_1.index + replaceInput_1.length; + } while (replaceMatch_1 = decodeRegExp.exec(text)); + if (replaceLastIndex_1 !== text.length) { + replaceResult_1 += text.substring(replaceLastIndex_1); + } + } else { + replaceResult_1 = text; + } + return replaceResult_1; + } + exports.decode = decode2; + } +}); -// src/utils/logger.js -var import_src = __toESM(require_src(), 1); -var name = "feed-reader"; -var info = (0, import_src.default)(`${name}:info`); -var error = (0, import_src.default)(`${name}:error`); -var warning = (0, import_src.default)(`${name}:warning`); -var logger_default = { - info: (0, import_src.default)(`${name}:info`), - error: (0, import_src.default)(`${name}:error`), - warning: (0, import_src.default)(`${name}:warning`) -}; +// src/main.js +var main_exports = {}; +__export(main_exports, { + getReaderOptions: () => getReaderOptions, + getRequestOptions: () => getRequestOptions, + read: () => read, + setReaderOptions: () => setReaderOptions, + setRequestOptions: () => setRequestOptions +}); +module.exports = __toCommonJS(main_exports); -// src/utils/xml2obj.js -var xml2obj_default = (xml = "") => { - const options = { - ignoreAttributes: false - }; - info("Parsing XML data..."); - const parser = new import_fxp.XMLParser(options); - const jsonObj = parser.parse(xml); - return jsonObj; +// src/utils/linker.js +var isValid = (url = "") => { + try { + const ourl = new URL(url); + return ourl !== null && ourl.protocol.startsWith("http"); + } catch (err) { + return false; + } }; - -// src/utils/purifyUrl.js var blacklistKeys = [ "CNDID", "__twitter_impression", @@ -14466,7 +14399,7 @@ var blacklistKeys = [ "pk_medium", "pk_campaign" ]; -var purifyUrl_default = (url) => { +var purify = (url) => { try { const pureUrl = new URL(url); blacklistKeys.forEach((key) => { @@ -14478,54 +14411,166 @@ var purifyUrl_default = (url) => { } }; -// src/utils/parser.js -var toISODateString = (dstr) => { +// src/utils/retrieve.js +var import_axios = __toESM(require_axios2(), 1); +var import_bellajs2 = __toESM(require_bella(), 1); + +// src/config.js +var import_bellajs = __toESM(require_bella(), 1); +var requestOptions = { + headers: { + "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0", + "accept-encoding": "*" + }, + responseType: "text", + responseEncoding: "utf8", + timeout: 3e4, + maxRedirects: 5 +}; +var readerOptions = { + descriptionMaxLen: 210, + includeFullContent: false, + convertPubDateToISO: true +}; +var getRequestOptions = () => { + return (0, import_bellajs.clone)(requestOptions); +}; +var setRequestOptions = (opts) => { + (0, import_bellajs.copies)(opts, requestOptions); +}; +var getReaderOptions = () => { + return (0, import_bellajs.clone)(readerOptions); +}; +var setReaderOptions = (opts) => { + (0, import_bellajs.copies)(opts, readerOptions); +}; + +// src/utils/retrieve.js +var retrieve_default = async (url) => { try { - return new Date(dstr).toISOString(); + const res = await import_axios.default.get(url, getRequestOptions()); + const contentType = res.headers["content-type"]; + const { data, status } = res; + return (0, import_bellajs2.isObject)(data) ? { type: "json", json: data, status, contentType } : { type: "xml", text: data.trim(), status, contentType }; } catch (err) { - return ""; + throw new Error(`${err.name}: ${err.message}`); } }; -var toDate = (val) => { - return val ? toISODateString(val) : ""; + +// src/utils/xmlparser.js +var import_bellajs3 = __toESM(require_bella(), 1); +var import_fast_xml_parser = __toESM(require_fxp(), 1); +var isRSS = (data = {}) => { + return (0, import_bellajs3.hasProperty)(data, "rss") && (0, import_bellajs3.hasProperty)(data.rss, "channel"); }; -var toText = (val) => { - const txt = (0, import_bellajs3.isObject)(val) ? val._text || val["#text"] || val._cdata || val.$t : val; - return txt ? (0, import_html_entities.decode)(String(txt).trim()) : ""; +var isAtom = (data = {}) => { + return (0, import_bellajs3.hasProperty)(data, "feed") && (0, import_bellajs3.hasProperty)(data.feed, "entry"); }; -var toDesc = (val) => { - const txt = toText(val); - const stripped = (0, import_bellajs3.stripTags)(txt); - return (0, import_bellajs3.truncate)(stripped, 240); +var validate = (xml) => { + return !(0, import_bellajs3.isString)(xml) || !xml.length ? false : import_fast_xml_parser.XMLValidator.validate(xml) === true; }; -var toLink = (val) => { - const getEntryLink = (links) => { - const link = links.find((item) => { - return item.rel === "alternate"; - }); - return link ? toText(link.href) : ""; +var xml2obj = (xml = "") => { + const options = { + ignoreAttributes: false }; - return (0, import_bellajs3.isString)(val) ? toText(val) : (0, import_bellajs3.isObject)(val) && (0, import_bellajs3.hasProperty)(val, "href") ? toText(val.href) : (0, import_bellajs3.isObject)(val) && (0, import_bellajs3.hasProperty)(val, "@_href") ? toText(val["@_href"]) : (0, import_bellajs3.isObject)(val) && (0, import_bellajs3.hasProperty)(val, "_attributes") ? toText(val._attributes.href) : (0, import_bellajs3.isArray)(val) ? toLink(val[0]) : getEntryLink(val); + const parser = new import_fast_xml_parser.XMLParser(options); + const jsonObj = parser.parse(xml); + return jsonObj; }; -var nomalizeRssItem = (entry) => { - return { - title: toText(entry.title), - link: purifyUrl_default(toLink(entry.link)), - description: toDesc(entry.description), - published: toDate(toText(entry.pubDate)) + +// src/utils/parseJsonFeed.js +var import_bellajs5 = __toESM(require_bella(), 1); + +// src/utils/normalizer.js +var import_bellajs4 = __toESM(require_bella(), 1); +var toISODateString = (dstr) => { + try { + return dstr ? new Date(dstr).toISOString() : ""; + } catch (err) { + return ""; + } +}; +var buildDescription = (val) => { + const { descriptionMaxLen } = getReaderOptions(); + const stripped = (0, import_bellajs4.stripTags)(val); + return (0, import_bellajs4.truncate)(stripped, descriptionMaxLen).replace(/\n+/g, " "); +}; + +// src/utils/parseJsonFeed.js +var transform = (item) => { + const { + includeFullContent, + convertPubDateToISO + } = getReaderOptions(); + const { + title, + url: link, + date_published: pubDate, + summary, + content_html: htmlContent, + content_text: textContent + } = item; + const published = convertPubDateToISO ? toISODateString(pubDate) : pubDate; + const entry = { + title, + link, + published, + description: buildDescription(textContent || htmlContent || summary) }; + if (includeFullContent) { + entry.content = htmlContent || textContent || summary; + } + return entry; }; -var nomalizeAtomItem = (entry) => { +var parseJson = (data) => { + const { + title = "", + home_page_url = "", + description = "", + language = "", + items: item = [] + } = data; + const items = (0, import_bellajs5.isArray)(item) ? item : [item]; return { - title: toText(entry.title), - link: purifyUrl_default(toLink(entry.link)), - description: toDesc(entry.summary || entry.description || entry.content), - published: toDate(toText(entry.updated || entry.published)) + title, + link: home_page_url, + description, + language, + published: "", + generator: "", + entries: items.map(transform) }; }; -var parseRSS = (xmldata) => { - const { rss = {} } = xmldata; - const { channel = {} } = rss; +var parseJsonFeed_default = (data) => { + return parseJson(data); +}; + +// src/utils/parseRssFeed.js +var import_bellajs6 = __toESM(require_bella(), 1); +var transform2 = (item) => { + const { + includeFullContent, + convertPubDateToISO + } = getReaderOptions(); + const { + title, + link, + pubDate, + description + } = item; + const published = convertPubDateToISO ? toISODateString(pubDate) : pubDate; + const entry = { + title, + link: purify(link), + published, + description: buildDescription(description) + }; + if (includeFullContent) { + entry.content = description; + } + return entry; +}; +var parseRss = (data) => { const { title = "", link = "", @@ -14534,123 +14579,119 @@ var parseRSS = (xmldata) => { language = "", lastBuildDate = "", item = [] - } = channel; - const entries = (0, import_bellajs3.isArray)(item) ? item.map(nomalizeRssItem) : [nomalizeRssItem(item)]; + } = data.rss.channel; + const items = (0, import_bellajs6.isArray)(item) ? item : [item]; return { title, - link: purifyUrl_default(link), + link, description, - generator, language, - published: toDate(lastBuildDate), - entries + generator, + published: toISODateString(lastBuildDate), + entries: items.map(transform2) + }; +}; +var parseRssFeed_default = (data) => { + return parseRss(data); +}; + +// src/utils/parseAtomFeed.js +var import_bellajs7 = __toESM(require_bella(), 1); +var import_html_entities = __toESM(require_lib(), 1); +var getText = (val) => { + const txt = (0, import_bellajs7.isObject)(val) ? val._text || val["#text"] || val._cdata || val.$t : val; + return txt ? (0, import_html_entities.decode)(String(txt).trim()) : ""; +}; +var getLink = (val = [], id = "") => { + if (isValid(id)) { + return purify(id); + } + const getEntryLink = (links) => { + const items = links.map((item) => { + return getLink(item); + }); + return items.length > 0 ? items[0] : null; }; + return (0, import_bellajs7.isString)(val) ? getText(val) : (0, import_bellajs7.isObject)(val) && (0, import_bellajs7.hasProperty)(val, "href") ? getText(val.href) : (0, import_bellajs7.isObject)(val) && (0, import_bellajs7.hasProperty)(val, "@_href") ? getText(val["@_href"]) : (0, import_bellajs7.isObject)(val) && (0, import_bellajs7.hasProperty)(val, "_attributes") ? getText(val._attributes.href) : (0, import_bellajs7.isArray)(val) ? getEntryLink(val) : null; }; -var parseAtom = (xmldata) => { - const { feed = {} } = xmldata; +var transform3 = (item) => { const { + includeFullContent, + convertPubDateToISO + } = getReaderOptions(); + const { + id, + title, + updated, + published, + link, + summary, + content + } = item; + const pubDate = updated || published; + const htmlContent = getText(content); + const entry = { + title: getText(title), + link: getLink(link, id), + published: convertPubDateToISO ? toISODateString(pubDate) : pubDate, + description: buildDescription(htmlContent || summary) + }; + if (includeFullContent) { + entry.content = htmlContent; + } + return entry; +}; +var parseAtom = (data) => { + const { + id, title = "", link = "", subtitle = "", generator = "", language = "", updated = "", - entry = [] - } = feed; - const entries = (0, import_bellajs3.isArray)(entry) ? entry.map(nomalizeAtomItem) : [nomalizeAtomItem(entry)]; + entry: item = [] + } = data.feed; + const items = (0, import_bellajs7.isArray)(item) ? item : [item]; return { - title: toText(title), - link: purifyUrl_default(toLink(link)), + title: getText(title), + link: getLink(link, id), description: subtitle, - generator, language, - published: toDate(updated), - entries + generator, + published: toISODateString(updated), + entries: items.map(transform3) }; }; -var parse = (xml) => { - const jsonObj = xml2obj_default(xml); - return isRSS(jsonObj) ? parseRSS(jsonObj) : isAtom(jsonObj) ? parseAtom(jsonObj) : null; -}; - -// src/utils/isValidUrl.js -var isValidUrl_default = (url = "") => { - try { - const ourl = new URL(url); - return ourl !== null && ourl.protocol.startsWith("http"); - } catch (err) { - return false; - } +var parseAtomFeed_default = (data) => { + return parseAtom(data); }; // src/main.js -var eventEmitter = new import_events.default(); -var runWhenComplete = (url, result = null, error2 = null) => { - eventEmitter.emit("complete", url, result, error2); - return result; -}; var read = async (url) => { - try { - if (!isValidUrl_default(url)) { - const erdata = { - error: "Error occurred while verifying feed URL", - reason: "Invalid URL" - }; - eventEmitter.emit("error", url, erdata); - return runWhenComplete(url, null, erdata); - } - const xml = await retrieve_default(url); - if (!validate(xml)) { - const erdata = { - error: "Error occurred while validating XML format", - reason: "The XML document is not well-formed" - }; - eventEmitter.emit("error", url, erdata); - return runWhenComplete(url, null, erdata); - } - try { - const feed = parse(xml); - if (feed) { - eventEmitter.emit("success", url, feed); - } - return runWhenComplete(url, feed); - } catch (er) { - const erdata = { - error: "Error occurred while parsing XML structure", - reason: er.message - }; - eventEmitter.emit("error", url, erdata); - return runWhenComplete(url, null, erdata); - } - } catch (err) { - const erdata = { - error: "Error occurred while retrieving remote XML data", - reason: err.message - }; - eventEmitter.emit("error", url, erdata); - return runWhenComplete(url, null, erdata); + if (!isValid(url)) { + throw new Error("Input param must be a valid URL"); } -}; -var onComplete = (fn) => { - eventEmitter.on("complete", fn); -}; -var onSuccess = (fn) => { - eventEmitter.on("success", fn); -}; -var onError = (fn) => { - eventEmitter.on("error", fn); -}; -var resetEvents = () => { - eventEmitter.removeAllListeners(); + const data = await retrieve_default(url); + if (!data.text && !data.json) { + throw new Error(`Failed to load content from "${url}"`); + } + const { type, json, text } = data; + if (type === "json") { + return parseJsonFeed_default(json); + } + if (!validate(text)) { + throw new Error("The XML document is not well-formed"); + } + const xml = xml2obj(text); + return isRSS(xml) ? parseRssFeed_default(xml) : isAtom(xml) ? parseAtomFeed_default(xml) : null; }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { + getReaderOptions, getRequestOptions, - onComplete, - onError, - onSuccess, read, - resetEvents, + setReaderOptions, setRequestOptions }); /*! diff --git a/dist/cjs/package.json b/dist/cjs/package.json index a6e111b..6f52999 100644 --- a/dist/cjs/package.json +++ b/dist/cjs/package.json @@ -1,5 +1,5 @@ { "name": "feed-reader-cjs", - "version": "6.0.0rc2", + "version": "6.0.0rc3", "main": "./feed-reader.js" } \ No newline at end of file diff --git a/eval.js b/eval.js index dce50aa..29715ee 100755 --- a/eval.js +++ b/eval.js @@ -1,23 +1,17 @@ // eval.js -import { writeFileSync } from 'fs' +// import { writeFileSync } from 'fs' -import { read, onComplete, onSuccess, onError } from './src/main.js' +import { read } from './src/main.js' const extractFromUrl = async (url) => { - onComplete((result, url) => { - console.log('onComplete', url) - }) - onSuccess((feed, url) => { - console.log('onSuccess', url) - writeFileSync('./output.json', JSON.stringify(feed, undefined, 2), 'utf8') - }) - onError((e, url) => { - console.log('onError', url) - console.log(e) - }) - const feed = await read(url) - console.log(feed) + try { + const feed = await read(url) + console.log(feed) + // writeFileSync('output.json', JSON.stringify(feed, undefined, 2), 'utf8') + } catch (err) { + console.log(err) + } } const init = (argv) => { diff --git a/package.json b/package.json index 2a937bb..463b69e 100755 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "6.0.0rc2", + "version": "6.0.0rc3", "name": "feed-reader", "description": "Load and parse ATOM/RSS data from given feed url", "homepage": "https://www.npmjs.com/package/feed-reader", @@ -8,8 +8,7 @@ "url": "git@github.com:ndaidong/feed-reader.git" }, "author": "@ndaidong", - "main": "./dist/cjs/feed-reader.js", - "module": "./src/main.js", + "main": "./src/main.js", "type": "module", "types": "./index.d.ts", "engines": { @@ -17,7 +16,6 @@ }, "scripts": { "lint": "standard .", - "pretest": "npm run lint", "test": "NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --verbose --coverage=true --unhandled-rejections=strict --detectOpenHandles", "build": "node build src/main.js", "eval": "DEBUG=*:* node eval", @@ -26,8 +24,7 @@ }, "dependencies": { "axios": "^0.27.2", - "bellajs": "^11.0.0rc3", - "debug": "^4.3.4", + "bellajs": "^11.0.3", "fast-xml-parser": "^4.0.9", "html-entities": "^2.3.3" }, diff --git a/src/config.js b/src/config.js index 5452fb4..5de8f76 100644 --- a/src/config.js +++ b/src/config.js @@ -5,7 +5,7 @@ import { clone, copies } from 'bellajs' const requestOptions = { headers: { 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0', - 'accept-encoding': 'deflate,zlib,gzip' + 'accept-encoding': '*' }, responseType: 'text', responseEncoding: 'utf8', @@ -13,6 +13,12 @@ const requestOptions = { maxRedirects: 5 } +const readerOptions = { + descriptionMaxLen: 210, // max num of chars for description + includeFullContent: false, + convertPubDateToISO: true +} + export const getRequestOptions = () => { return clone(requestOptions) } @@ -20,3 +26,11 @@ export const getRequestOptions = () => { export const setRequestOptions = (opts) => { copies(opts, requestOptions) } + +export const getReaderOptions = () => { + return clone(readerOptions) +} + +export const setReaderOptions = (opts) => { + copies(opts, readerOptions) +} diff --git a/src/config.test.js b/src/config.test.js index 6cc580e..3600361 100644 --- a/src/config.test.js +++ b/src/config.test.js @@ -5,23 +5,45 @@ import { hasProperty } from 'bellajs' import { setRequestOptions, - getRequestOptions + getRequestOptions, + setReaderOptions, + getReaderOptions } from './config.js' -test('Testing setRequestOptions/getRequestOptions methods', () => { - setRequestOptions({ - headers: { - authorization: 'bearer ' - }, - timeout: 20, - somethingElse: 1000 +const defaultRequestOptions = getRequestOptions() +const defaultReaderOptions = getReaderOptions() + +afterAll(() => { + return setReaderOptions(defaultReaderOptions) && setRequestOptions(defaultRequestOptions) +}) + +describe('check methods from `config`', () => { + test('Testing setRequestOptions/getRequestOptions methods', () => { + setRequestOptions({ + headers: { + authorization: 'bearer ' + }, + timeout: 20, + somethingElse: 1000 + }) + + const { headers, timeout, somethingElse } = getRequestOptions() + + expect(hasProperty(headers, 'authorization')).toBeTruthy() + expect(hasProperty(headers, 'user-agent')).toBeTruthy() + expect(hasProperty(headers, 'accept-encoding')).toBeTruthy() + expect(timeout).toEqual(20) + expect(somethingElse).toEqual(1000) }) + test('Testing setReaderOptions/getReaderOptions methods', () => { + setReaderOptions({ + descriptionMaxLen: 250, + includeFullContent: true + }) - const { headers, timeout, somethingElse } = getRequestOptions() + const { descriptionMaxLen, includeFullContent } = getReaderOptions() - expect(hasProperty(headers, 'authorization')).toBeTruthy() - expect(hasProperty(headers, 'user-agent')).toBeTruthy() - expect(hasProperty(headers, 'accept-encoding')).toBeTruthy() - expect(timeout).toEqual(20) - expect(somethingElse).toEqual(1000) + expect(descriptionMaxLen).toEqual(250) + expect(includeFullContent).toEqual(true) + }) }) diff --git a/src/main.js b/src/main.js index 0c6a01b..942ebf1 100755 --- a/src/main.js +++ b/src/main.js @@ -3,85 +3,44 @@ * @ndaidong **/ -import EventEmitter from 'events' +import { isValid as isValidUrl } from './utils/linker.js' -import getXML from './utils/retrieve.js' -import { parse } from './utils/parser.js' - -import isValidUrl from './utils/isValidUrl.js' -import { validate } from './utils/validator.js' +import retrieve from './utils/retrieve.js' +import { validate, xml2obj, isRSS, isAtom } from './utils/xmlparser.js' +import parseJsonFeed from './utils/parseJsonFeed.js' +import parseRssFeed from './utils/parseRssFeed.js' +import parseAtomFeed from './utils/parseAtomFeed.js' export { getRequestOptions, - setRequestOptions + setRequestOptions, + getReaderOptions, + setReaderOptions } from './config.js' -const eventEmitter = new EventEmitter() - -const runWhenComplete = (url, result = null, error = null) => { - eventEmitter.emit('complete', url, result, error) - return result -} - export const read = async (url) => { - try { - if (!isValidUrl(url)) { - const erdata = { - error: 'Error occurred while verifying feed URL', - reason: 'Invalid URL' - } - eventEmitter.emit('error', url, erdata) - return runWhenComplete(url, null, erdata) - } - const xml = await getXML(url) - - if (!validate(xml)) { - const erdata = { - error: 'Error occurred while validating XML format', - reason: 'The XML document is not well-formed' - } - eventEmitter.emit('error', url, erdata) - return runWhenComplete(url, null, erdata) - } - - try { - const feed = parse(xml) - if (feed) { - eventEmitter.emit('success', url, feed) - } - - return runWhenComplete(url, feed) - } catch (er) { - const erdata = { - error: 'Error occurred while parsing XML structure', - reason: er.message - } - eventEmitter.emit('error', url, erdata) - - return runWhenComplete(url, null, erdata) - } - } catch (err) { - const erdata = { - error: 'Error occurred while retrieving remote XML data', - reason: err.message - } - eventEmitter.emit('error', url, erdata) - return runWhenComplete(url, null, erdata) + if (!isValidUrl(url)) { + throw new Error('Input param must be a valid URL') + } + const data = await retrieve(url) + if (!data.text && !data.json) { + throw new Error(`Failed to load content from "${url}"`) } -} -export const onComplete = (fn) => { - eventEmitter.on('complete', fn) -} + const { type, json, text } = data -export const onSuccess = (fn) => { - eventEmitter.on('success', fn) -} + if (type === 'json') { + return parseJsonFeed(json) + } -export const onError = (fn) => { - eventEmitter.on('error', fn) -} + if (!validate(text)) { + throw new Error('The XML document is not well-formed') + } -export const resetEvents = () => { - eventEmitter.removeAllListeners() + const xml = xml2obj(text) + return isRSS(xml) + ? parseRssFeed(xml) + : isAtom(xml) + ? parseAtomFeed(xml) + : null } diff --git a/src/main.test.js b/src/main.test.js old mode 100755 new mode 100644 index 20ed309..91b9173 --- a/src/main.test.js +++ b/src/main.test.js @@ -3,14 +3,17 @@ import { readFileSync } from 'fs' -import { hasProperty } from 'bellajs' import nock from 'nock' -import { read, onSuccess, onError, onComplete, resetEvents } from './main.js' +import { hasProperty } from 'bellajs' + +import { read, getReaderOptions, setReaderOptions } from './main.js' const feedAttrs = 'title link description generator language published entries'.split(' ') const entryAttrs = 'title link description published'.split(' ') +const defaultReaderOptions = getReaderOptions() + const parseUrl = (url) => { const re = new URL(url) return { @@ -19,154 +22,157 @@ const parseUrl = (url) => { } } -test('test read a non-string link', async () => { - const url = [] - onError((rss, err) => { - expect(rss).toEqual(url) - expect(err.error).toEqual('Error occurred while verifying feed URL') - expect(err.reason).toEqual('Invalid URL') - }) - onComplete((rss, feed, err) => { - expect(rss).toEqual(url) - expect(feed).toEqual(null) - expect(err.error).toEqual('Error occurred while verifying feed URL') - expect(err.reason).toEqual('Invalid URL') - }) - const re = await read(url) - expect(re).toEqual(null) - resetEvents() +afterAll(() => { + return setReaderOptions(defaultReaderOptions) }) -test('test read a fake link', async () => { - const url = 'https://somewhere.xyz/alpha/beta' - const { baseUrl, path } = parseUrl(url) - nock(baseUrl).head(path).reply(404) - nock(baseUrl).get(path).reply(404) - - onError((rss, err) => { - expect(rss).toEqual(url) - expect(err.error).toEqual('Error occurred while retrieving remote XML data') - expect(err.reason).toEqual('Request failed with status code 404') - }) - onComplete((rss, feed, err) => { - expect(rss).toEqual(url) - expect(feed).toEqual(null) - expect(err.error).toEqual('Error occurred while retrieving remote XML data') - expect(err.reason).toEqual('Request failed with status code 404') +describe('test read() function with common issues', () => { + test('read feed from a non-string link', () => { + expect(read([])).rejects.toThrow(new Error('Input param must be a valid URL')) }) - const re = await read(url) - expect(re).toEqual(null) - resetEvents() -}) -test('test read from invalid xml', async () => { - const url = 'https://averybad-source.elsewhere/rss' - const xml = '' - const { baseUrl, path } = parseUrl(url) - nock(baseUrl).head(path).reply(200) - nock(baseUrl).get(path).reply(200, xml, { - 'Content-Type': 'application/xml' + test('read feed from a 404 link', () => { + const url = 'https://somewhere.xyz/alpha/beta' + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(404) + expect(read(url)).rejects.toThrow(new Error('AxiosError: Request failed with status code 404')) }) - onError((rss, err) => { - expect(rss).toEqual(url) - expect(err.error).toEqual('Error occurred while validating XML format') - expect(err.reason).toEqual('The XML document is not well-formed') + + test('read feed from empty xml', () => { + const url = 'https://empty-source.elsewhere/rss' + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, '', { + 'Content-Type': 'application/xml' + }) + expect(read(url)).rejects.toThrow(new Error(`Failed to load content from "${url}"`)) }) - onComplete((rss, feed, err) => { - expect(rss).toEqual(url) - expect(feed).toEqual(null) - expect(err.error).toEqual('Error occurred while validating XML format') - expect(err.reason).toEqual('The XML document is not well-formed') + + test('read feed from invalid xml', async () => { + const url = 'https://averybad-source.elsewhere/rss' + const xml = '' + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, xml, { + 'Content-Type': 'application/xml' + }) + expect(read(url)).rejects.toThrow(new Error('The XML document is not well-formed')) }) - const re = await read(url) - expect(re).toEqual(null) - resetEvents() }) -const runtest = ({ type, url, file, size }) => { - describe(`test if ${type} parsing works correctly`, () => { - const state = {} - test(`test read from good ${type} source`, async () => { - const xml = readFileSync(file, 'utf8') - const { baseUrl, path } = parseUrl(url) - nock(baseUrl).head(path).reply(200) - nock(baseUrl).get(path).reply(200, xml, { - 'Content-Type': 'application/xml' - }) - const result = await read(url) - expect(result).toBeInstanceOf(Object) - expect(result.entries.length).toEqual(size) - state.data = result - state.firstEntry = result.entries[0] +describe('test read() standard feed', (done) => { + test('read rss feed from Google', async () => { + const url = 'https://some-news-page.tld/rss' + const xml = readFileSync('test-data/rss-feed-standard-realworld.xml', 'utf8') + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, xml, { + 'Content-Type': 'application/xml' }) - + const result = await read(url) feedAttrs.forEach((k) => { - test(` test if ${type} feed has property "${k}"`, () => { - expect(hasProperty(state.data, k)).toBe(true) - }) + expect(hasProperty(result, k)).toBe(true) }) entryAttrs.forEach((k) => { - test(` test if ${type} feed entry has property "${k}"`, () => { - expect(hasProperty(state.firstEntry, k)).toBe(true) - }) + expect(hasProperty(result.entries[0], k)).toBe(true) }) }) -} -const sources = [ - { - type: 'atom', - url: 'https://news.google.com/atom', - file: 'test-data/atom.xml', - size: 2 - }, - { - type: 'atom', - url: 'https://news.google.com/atom-with-single-item', - file: 'test-data/atom-with-single-item.xml', - size: 1 - }, - { - type: 'rss', - url: 'https://news.google.com/rss', - file: 'test-data/rss.xml', - size: 2 - }, - { - type: 'rss', - url: 'https://news.google.com/rss-with-single-item', - file: 'test-data/rss-with-single-item.xml', - size: 1 - } -] - -sources.forEach(runtest) + test('read atom feed from Google', async () => { + const url = 'https://some-news-page.tld/atom' + const xml = readFileSync('test-data/atom-feed-standard-realworld.xml', 'utf8') + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, xml, { + 'Content-Type': 'application/xml' + }) + const result = await read(url) + feedAttrs.forEach((k) => { + expect(hasProperty(result, k)).toBe(true) + }) + entryAttrs.forEach((k) => { + expect(hasProperty(result.entries[0], k)).toBe(true) + }) + }) -test('test read from a more complicate atom source', async () => { - const url = 'https://headline.com/atom' - const xml = readFileSync('test-data/another-atom.xml', 'utf8') - const { baseUrl, path } = parseUrl(url) - nock(baseUrl).head(path).reply(200) - nock(baseUrl).get(path).reply(200, xml, { - 'Content-Type': 'application/xml' + test('read atom feed which contains multi links', async () => { + const url = 'https://some-news-page.tld/atom/multilinks' + const xml = readFileSync('test-data/atom-multilinks.xml', 'utf8') + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, xml, { + 'Content-Type': 'application/xml' + }) + const result = await read(url) + feedAttrs.forEach((k) => { + expect(hasProperty(result, k)).toBe(true) + }) + entryAttrs.forEach((k) => { + expect(hasProperty(result.entries[0], k)).toBe(true) + }) }) - onSuccess((rss, feed) => { - expect(rss).toEqual(url) - expect(feed).toBeInstanceOf(Object) + test('read json feed from Micro.blog', async () => { + const url = 'https://some-news-page.tld/json' + const json = readFileSync('test-data/json-feed-standard-realworld.json', 'utf8') + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, json, { + 'Content-Type': 'application/json' + }) + const result = await read(url) feedAttrs.forEach((k) => { - expect(hasProperty(feed, k)).toBe(true) + expect(hasProperty(result, k)).toBe(true) + }) + entryAttrs.forEach((k) => { + expect(hasProperty(result.entries[0], k)).toBe(true) }) }) +}) + +describe('test read() standard feed full content', () => { + setReaderOptions({ includeFullContent: true }) + const newEntryAttrs = [...entryAttrs, 'content'] - const result = await read(url) - expect(result).toBeInstanceOf(Object) - feedAttrs.forEach((k) => { - expect(hasProperty(result, k)).toBe(true) + test('read rss feed from Google', async () => { + const url = 'https://some-news-page.tld/rss' + const xml = readFileSync('test-data/rss-feed-standard-realworld.xml', 'utf8') + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, xml, { + 'Content-Type': 'application/xml' + }) + const result = await read(url) + feedAttrs.forEach((k) => { + expect(hasProperty(result, k)).toBe(true) + }) + newEntryAttrs.forEach((k) => { + expect(hasProperty(result.entries[0], k)).toBe(true) + }) }) - entryAttrs.forEach((k) => { - expect(hasProperty(result.entries[0], k)).toBe(true) + + test('read atom feed from Google', async () => { + const url = 'https://some-news-page.tld/atom' + const xml = readFileSync('test-data/atom-feed-standard-realworld.xml', 'utf8') + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, xml, { + 'Content-Type': 'application/xml' + }) + const result = await read(url) + feedAttrs.forEach((k) => { + expect(hasProperty(result, k)).toBe(true) + }) + newEntryAttrs.forEach((k) => { + expect(hasProperty(result.entries[0], k)).toBe(true) + }) }) - resetEvents() + test('read json feed from Micro.blog', async () => { + const url = 'https://some-news-page.tld/json' + const json = readFileSync('test-data/json-feed-standard-realworld.json', 'utf8') + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, json, { + 'Content-Type': 'application/json' + }) + const result = await read(url) + feedAttrs.forEach((k) => { + expect(hasProperty(result, k)).toBe(true) + }) + newEntryAttrs.forEach((k) => { + expect(hasProperty(result.entries[0], k)).toBe(true) + }) + }) }) diff --git a/src/utils/isValidUrl.js b/src/utils/isValidUrl.js deleted file mode 100755 index 5e22a45..0000000 --- a/src/utils/isValidUrl.js +++ /dev/null @@ -1,10 +0,0 @@ -// utils -> isValidUrl - -export default (url = '') => { - try { - const ourl = new URL(url) - return ourl !== null && ourl.protocol.startsWith('http') - } catch (err) { - return false - } -} diff --git a/src/utils/purifyUrl.js b/src/utils/linker.js similarity index 72% rename from src/utils/purifyUrl.js rename to src/utils/linker.js index 625d9df..a4bf36a 100755 --- a/src/utils/purifyUrl.js +++ b/src/utils/linker.js @@ -1,4 +1,22 @@ -// utils -> purifyUrl +// utils -> linker + +export const isValid = (url = '') => { + try { + const ourl = new URL(url) + return ourl !== null && ourl.protocol.startsWith('http') + } catch (err) { + return false + } +} + +export const absolutify = (fullUrl = '', relativeUrl = '') => { + try { + const result = new URL(relativeUrl, fullUrl) + return result.toString() + } catch (err) { + return '' + } +} const blacklistKeys = [ 'CNDID', @@ -60,7 +78,7 @@ const blacklistKeys = [ 'pk_campaign' ] -export default (url) => { +export const purify = (url) => { try { const pureUrl = new URL(url) diff --git a/src/utils/linker.test.js b/src/utils/linker.test.js new file mode 100755 index 0000000..36bf904 --- /dev/null +++ b/src/utils/linker.test.js @@ -0,0 +1,138 @@ +// linker.test +/* eslint-env jest */ + +import { isValid, absolutify, purify } from './linker.js' + +describe('test exported methods from `linker`', () => { + const cases = [ + { + url: 'https://www.23hq.com', + expected: true + }, + { + url: 'https://secure.actblue.com', + expected: true + }, + { + url: 'https://docs.microsoft.com/en-us/azure/iot-edge/quickstart?view=iotedge-2018-06', + expected: true + }, + { + url: 'http://192.168.1.199:8081/example/page', + expected: true + }, + { + url: 'ftp://192.168.1.199:8081/example/page', + expected: false + }, + { + url: '', + expected: false + }, + { + url: null, + expected: false + }, + { + url: { a: 'x' }, + expected: false + } + ] + cases.forEach(({ url, expected }) => { + test(`isValid("${url}") must return "${expected}"`, () => { + const result = isValid(url) + expect(result).toEqual(expected) + }) + }) + + const entries = [ + { + full: '', + expected: '' + }, + { + relative: {}, + expected: '' + }, + { + full: 'https://some.where/article/abc-xyz', + relative: 'category/page.html', + expected: 'https://some.where/article/category/page.html' + }, + { + full: 'https://some.where/article/abc-xyz', + relative: '../category/page.html', + expected: 'https://some.where/category/page.html' + }, + { + full: 'https://some.where/blog/authors/article/abc-xyz', + relative: '/category/page.html', + expected: 'https://some.where/category/page.html' + }, + { + full: 'https://some.where/article/abc-xyz', + expected: 'https://some.where/article/abc-xyz' + } + ] + entries.forEach((entry) => { + const { + full, + relative, + expected + } = entry + test(`absolutify("${full}", "${relative}") must become "${expected}"`, () => { + const result = absolutify(full, relative) + expect(result).toEqual(expected) + }) + }) + + test('test url purify() with invalid url', () => { + const urls = [ + null, + '', + 123, + {} + ] + urls.forEach((url) => { + const result = purify(url) + expect(result).toEqual(null) + }) + }) + + test('test url purify() removing regular marketing params', () => { + const entries = [ + { + url: 'https://some.where/article/abc-xyz', + expected: 'https://some.where/article/abc-xyz' + }, + { + url: 'https://some.where/article/abc-xyz#name,bob', + expected: 'https://some.where/article/abc-xyz' + }, + { + url: 'https://some.where/article/abc-xyz?utm_source=news4&utm_medium=email&utm_campaign=spring-summer', + expected: 'https://some.where/article/abc-xyz' + }, + { + url: 'https://some.where/article/abc-xyz?q=3&utm_source=news4&utm_medium=email&utm_campaign=spring-summer', + expected: 'https://some.where/article/abc-xyz?q=3' + }, + { + url: 'https://some.where/article/abc-xyz?pk_source=news4&pk_medium=email&pk_campaign=spring-summer', + expected: 'https://some.where/article/abc-xyz' + }, + { + url: 'https://some.where/article/abc-xyz?q=3&pk_source=news4&pk_medium=email&pk_campaign=spring-summer', + expected: 'https://some.where/article/abc-xyz?q=3' + } + ] + entries.forEach((entry) => { + const { + url, + expected + } = entry + const result = purify(url) + expect(result).toEqual(expected) + }) + }) +}) diff --git a/src/utils/logger.js b/src/utils/logger.js deleted file mode 100755 index 0565d7b..0000000 --- a/src/utils/logger.js +++ /dev/null @@ -1,15 +0,0 @@ -// utils / logger - -import debug from 'debug/src/index.js' - -const name = 'feed-reader' - -export const info = debug(`${name}:info`) -export const error = debug(`${name}:error`) -export const warning = debug(`${name}:warning`) - -export default { - info: debug(`${name}:info`), - error: debug(`${name}:error`), - warning: debug(`${name}:warning`) -} diff --git a/src/utils/normalizer.js b/src/utils/normalizer.js new file mode 100644 index 0000000..217650e --- /dev/null +++ b/src/utils/normalizer.js @@ -0,0 +1,22 @@ +// normalizer + +import { + stripTags, + truncate +} from 'bellajs' + +import { getReaderOptions } from '../config.js' + +export const toISODateString = (dstr) => { + try { + return dstr ? (new Date(dstr)).toISOString() : '' + } catch (err) { + return '' + } +} + +export const buildDescription = (val) => { + const { descriptionMaxLen } = getReaderOptions() + const stripped = stripTags(val) + return truncate(stripped, descriptionMaxLen).replace(/\n+/g, ' ') +} diff --git a/src/utils/normalizer.test.js b/src/utils/normalizer.test.js new file mode 100644 index 0000000..bf5529e --- /dev/null +++ b/src/utils/normalizer.test.js @@ -0,0 +1,13 @@ +// normalizer.test +/* eslint-env jest */ + +import { toISODateString } from './normalizer.js' + +describe('test `normalizer` methods', () => { + test('test toISODateString()', () => { + expect(toISODateString('Thu, 28 Jul 2022 08:59:58 GMT')).toEqual('2022-07-28T08:59:58.000Z') + expect(toISODateString('2022-07-28T02:43:00.000000000Z')).toEqual('2022-07-28T02:43:00.000Z') + expect(toISODateString('')).toEqual('') + expect(toISODateString('Thi, 280 Jul 2022 108:79:68 XMT')).toEqual('') + }) +}) diff --git a/src/utils/parseAtomFeed.js b/src/utils/parseAtomFeed.js new file mode 100644 index 0000000..087b8b5 --- /dev/null +++ b/src/utils/parseAtomFeed.js @@ -0,0 +1,101 @@ +// parseAtomFeed.js + +// specs: https://datatracker.ietf.org/doc/html/rfc5023 +// refer: https://validator.w3.org/feed/docs/atom.html + +import { isString, isObject, isArray, hasProperty } from 'bellajs' +import { decode } from 'html-entities' + +import { + toISODateString, + buildDescription +} from './normalizer.js' + +import { isValid as isValidUrl, purify as purifyUrl } from './linker.js' + +import { getReaderOptions } from '../config.js' + +const getText = (val) => { + const txt = isObject(val) ? (val._text || val['#text'] || val._cdata || val.$t) : val + return txt ? decode(String(txt).trim()) : '' +} + +const getLink = (val = [], id = '') => { + if (isValidUrl(id)) { + return purifyUrl(id) + } + const getEntryLink = (links) => { + const items = links.map((item) => { + return getLink(item) + }) + return items.length > 0 ? items[0] : null + } + return isString(val) + ? getText(val) + : isObject(val) && hasProperty(val, 'href') + ? getText(val.href) + : isObject(val) && hasProperty(val, '@_href') + ? getText(val['@_href']) + : isObject(val) && hasProperty(val, '_attributes') + ? getText(val._attributes.href) + : isArray(val) ? getEntryLink(val) : null +} + +const transform = (item) => { + const { + includeFullContent, + convertPubDateToISO + } = getReaderOptions() + + const { + id, + title, + updated, + published, + link, + summary, + content + } = item + + const pubDate = updated || published + const htmlContent = getText(content) + const entry = { + title: getText(title), + link: getLink(link, id), + published: convertPubDateToISO ? toISODateString(pubDate) : pubDate, + description: buildDescription(htmlContent || summary) + } + if (includeFullContent) { + entry.content = htmlContent + } + return entry +} + +const parseAtom = (data) => { + const { + id, + title = '', + link = '', + subtitle = '', + generator = '', + language = '', + updated = '', + entry: item = [] + } = data.feed + + const items = isArray(item) ? item : [item] + + return { + title: getText(title), + link: getLink(link, id), + description: subtitle, + language, + generator, + published: toISODateString(updated), + entries: items.map(transform) + } +} + +export default (data) => { + return parseAtom(data) +} diff --git a/src/utils/parseJsonFeed.js b/src/utils/parseJsonFeed.js new file mode 100644 index 0000000..20b68b3 --- /dev/null +++ b/src/utils/parseJsonFeed.js @@ -0,0 +1,66 @@ +// parseJsonFeed.js + +// specs: https://www.jsonfeed.org/version/1.1/ + +import { isArray } from 'bellajs' + +import { + toISODateString, + buildDescription +} from './normalizer.js' + +import { getReaderOptions } from '../config.js' + +const transform = (item) => { + const { + includeFullContent, + convertPubDateToISO + } = getReaderOptions() + + const { + title, + url: link, + date_published: pubDate, + summary, + content_html: htmlContent, + content_text: textContent + } = item + + const published = convertPubDateToISO ? toISODateString(pubDate) : pubDate + const entry = { + title, + link, + published, + description: buildDescription(textContent || htmlContent || summary) + } + if (includeFullContent) { + entry.content = htmlContent || textContent || summary + } + return entry +} + +const parseJson = (data) => { + const { + title = '', + home_page_url = '', + description = '', + language = '', + items: item = [] + } = data + + const items = isArray(item) ? item : [item] + + return { + title, + link: home_page_url, + description, + language, + published: '', + generator: '', + entries: items.map(transform) + } +} + +export default (data) => { + return parseJson(data) +} diff --git a/src/utils/parseRssFeed.js b/src/utils/parseRssFeed.js new file mode 100644 index 0000000..b03a888 --- /dev/null +++ b/src/utils/parseRssFeed.js @@ -0,0 +1,68 @@ +// parseRssFeed.js + +// specs: https://www.rssboard.org/rss-specification + +import { isArray } from 'bellajs' + +import { + toISODateString, + buildDescription +} from './normalizer.js' + +import { purify as purifyUrl } from './linker.js' + +import { getReaderOptions } from '../config.js' + +const transform = (item) => { + const { + includeFullContent, + convertPubDateToISO + } = getReaderOptions() + + const { + title, + link, + pubDate, + description + } = item + + const published = convertPubDateToISO ? toISODateString(pubDate) : pubDate + const entry = { + title, + link: purifyUrl(link), + published, + description: buildDescription(description) + } + if (includeFullContent) { + entry.content = description + } + return entry +} + +const parseRss = (data) => { + const { + title = '', + link = '', + description = '', + generator = '', + language = '', + lastBuildDate = '', + item = [] + } = data.rss.channel + + const items = isArray(item) ? item : [item] + + return { + title, + link, + description, + language, + generator, + published: toISODateString(lastBuildDate), + entries: items.map(transform) + } +} + +export default (data) => { + return parseRss(data) +} diff --git a/src/utils/parser.js b/src/utils/parser.js deleted file mode 100755 index 2eeebd1..0000000 --- a/src/utils/parser.js +++ /dev/null @@ -1,131 +0,0 @@ -// utils / parser - -import { decode } from 'html-entities' - -import { - isString, - isArray, - isObject, - hasProperty, - stripTags, - truncate -} from 'bellajs' - -import { isRSS, isAtom } from './validator.js' -import xml2obj from './xml2obj.js' -import purifyUrl from './purifyUrl.js' - -const toISODateString = (dstr) => { - try { - return (new Date(dstr)).toISOString() - } catch (err) { - return '' - } -} - -const toDate = (val) => { - return val ? toISODateString(val) : '' -} - -const toText = (val) => { - const txt = isObject(val) ? (val._text || val['#text'] || val._cdata || val.$t) : val - return txt ? decode(String(txt).trim()) : '' -} - -const toDesc = (val) => { - const txt = toText(val) - const stripped = stripTags(txt) - return truncate(stripped, 240) -} - -const toLink = (val) => { - const getEntryLink = (links) => { - const link = links.find((item) => { - return item.rel === 'alternate' - }) - return link ? toText(link.href) : '' - } - return isString(val) - ? toText(val) - : isObject(val) && hasProperty(val, 'href') - ? toText(val.href) - : isObject(val) && hasProperty(val, '@_href') - ? toText(val['@_href']) - : isObject(val) && hasProperty(val, '_attributes') - ? toText(val._attributes.href) - : isArray(val) ? toLink(val[0]) : getEntryLink(val) -} - -const nomalizeRssItem = (entry) => { - return { - title: toText(entry.title), - link: purifyUrl(toLink(entry.link)), - description: toDesc(entry.description), - published: toDate(toText(entry.pubDate)) - } -} - -const nomalizeAtomItem = (entry) => { - return { - title: toText(entry.title), - link: purifyUrl(toLink(entry.link)), - description: toDesc(entry.summary || entry.description || entry.content), - published: toDate(toText(entry.updated || entry.published)) - } -} - -export const parseRSS = (xmldata) => { - const { rss = {} } = xmldata - const { channel = {} } = rss - const { - title = '', - link = '', - description = '', - generator = '', - language = '', - lastBuildDate = '', - item = [] - } = channel - - const entries = isArray(item) ? item.map(nomalizeRssItem) : [nomalizeRssItem(item)] - - return { - title, - link: purifyUrl(link), - description, - generator, - language, - published: toDate(lastBuildDate), - entries - } -} - -export const parseAtom = (xmldata) => { - const { feed = {} } = xmldata - const { - title = '', - link = '', - subtitle = '', - generator = '', - language = '', - updated = '', - entry = [] - } = feed - - const entries = isArray(entry) ? entry.map(nomalizeAtomItem) : [nomalizeAtomItem(entry)] - - return { - title: toText(title), - link: purifyUrl(toLink(link)), - description: subtitle, - generator, - language, - published: toDate(updated), - entries - } -} - -export const parse = (xml) => { - const jsonObj = xml2obj(xml) - return isRSS(jsonObj) ? parseRSS(jsonObj) : isAtom(jsonObj) ? parseAtom(jsonObj) : null -} diff --git a/src/utils/purifyUrl.test.js b/src/utils/purifyUrl.test.js deleted file mode 100755 index 141f65f..0000000 --- a/src/utils/purifyUrl.test.js +++ /dev/null @@ -1,54 +0,0 @@ -// purifyUrl.test -/* eslint-env jest */ - -import purifyUrl from './purifyUrl.js' - -test('test purifyUrl() with invalid url', () => { - const urls = [ - null, - '', - 123, - {} - ] - urls.forEach((url) => { - const result = purifyUrl(url) - expect(result).toEqual(null) - }) -}) - -test('test purifyUrl() removing regular marketing params', () => { - const entries = [ - { - url: 'https://some.where/article/abc-xyz', - expected: 'https://some.where/article/abc-xyz' - }, - { - url: 'https://some.where/article/abc-xyz#name,bob', - expected: 'https://some.where/article/abc-xyz' - }, - { - url: 'https://some.where/article/abc-xyz?utm_source=news4&utm_medium=email&utm_campaign=spring-summer', - expected: 'https://some.where/article/abc-xyz' - }, - { - url: 'https://some.where/article/abc-xyz?q=3&utm_source=news4&utm_medium=email&utm_campaign=spring-summer', - expected: 'https://some.where/article/abc-xyz?q=3' - }, - { - url: 'https://some.where/article/abc-xyz?pk_source=news4&pk_medium=email&pk_campaign=spring-summer', - expected: 'https://some.where/article/abc-xyz' - }, - { - url: 'https://some.where/article/abc-xyz?q=3&pk_source=news4&pk_medium=email&pk_campaign=spring-summer', - expected: 'https://some.where/article/abc-xyz?q=3' - } - ] - entries.forEach((entry) => { - const { - url, - expected - } = entry - const result = purifyUrl(url) - expect(result).toEqual(expected) - }) -}) diff --git a/src/utils/retrieve.js b/src/utils/retrieve.js index 0c7e299..6a8880e 100755 --- a/src/utils/retrieve.js +++ b/src/utils/retrieve.js @@ -1,10 +1,19 @@ // utils -> retrieve import axios from 'axios' +import { isObject } from 'bellajs' import { getRequestOptions } from '../config.js' export default async (url) => { - const res = await axios.get(url, getRequestOptions()) - return res.data.trim() + try { + const res = await axios.get(url, getRequestOptions()) + const contentType = res.headers['content-type'] + const { data, status } = res + return isObject(data) + ? { type: 'json', json: data, status, contentType } + : { type: 'xml', text: data.trim(), status, contentType } + } catch (err) { + throw new Error(`${err.name}: ${err.message}`) + } } diff --git a/src/utils/retrieve.test.js b/src/utils/retrieve.test.js index 7698b0a..fb38612 100755 --- a/src/utils/retrieve.test.js +++ b/src/utils/retrieve.test.js @@ -13,37 +13,29 @@ const parseUrl = (url) => { } } -test('test retrieve from good source', async () => { - const url = 'https://some.where/good/page' - const { baseUrl, path } = parseUrl(url) - nock(baseUrl).head(path).reply(200) - nock(baseUrl).get(path).reply(200, '
this is content
', { - 'Content-Type': 'application/xml' +describe('test retrieve() method', () => { + test('test retrieve with bad status code', async () => { + const url = 'https://some.where/bad/page' + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(500, 'Error 500') + expect(retrieve(url)).rejects.toThrow(new Error('AxiosError: Request failed with status code 500')) }) - const result = await retrieve(url) - expect(result).toBe('
this is content
') -}) -test('test retrieve from good source, but having \\r\\n before/after root xml', async () => { - const url = 'https://some.where/good/page' - const { baseUrl, path } = parseUrl(url) - nock(baseUrl).head(path).reply(200) - nock(baseUrl).get(path).reply(200, '\n\r\r\n\n
this is content
\n\r\r\n\n', { - 'Content-Type': 'application/xml' + test('test retrieve from good source', async () => { + const url = 'https://some.where/good/page' + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, '
this is content
') + const result = await retrieve(url) + expect(result.type).toEqual('xml') + expect(result.text).toEqual('
this is content
') }) - const result = await retrieve(url) - expect(result).toBe('
this is content
') -}) -// test('test retrieve with invalid response status code', async () => { -// const url = 'https://some.where/bad/page' -// const { baseUrl, path } = parseUrl(url) -// nock(baseUrl).head(path).reply(500) -// nock(baseUrl).get(path).reply(500, 'Error 500', { -// 'Content-Type': 'application/xml' -// }) -// const result = await retrieve(url) -// expect(typeof result).toBe('object') -// expect(typeof result.error).toBe('object', result.error) -// expect(typeof result.error.message).toBe('string') -// }) + test('test retrieve from good source, but having \\r\\n before/after root xml', async () => { + const url = 'https://some.where/good/page' + const { baseUrl, path } = parseUrl(url) + nock(baseUrl).get(path).reply(200, '\n\r\r\n\n
this is content
\n\r\r\n\n') + const result = await retrieve(url) + expect(result.type).toEqual('xml') + expect(result.text).toBe('
this is content
') + }) +}) diff --git a/src/utils/validator.js b/src/utils/validator.js deleted file mode 100755 index 2161d70..0000000 --- a/src/utils/validator.js +++ /dev/null @@ -1,17 +0,0 @@ -// utils / validator - -import { hasProperty } from 'bellajs' -import { XMLValidator } from 'fast-xml-parser' - -export const isRSS = (data = {}) => { - return hasProperty(data, 'rss') && hasProperty(data.rss, 'channel') -} - -export const isAtom = (data = {}) => { - return hasProperty(data, 'feed') && hasProperty(data.feed, 'entry') -} - -export const validate = (xml = '') => { - const result = XMLValidator.validate(xml) - return result === true -} diff --git a/src/utils/validator.test.js b/src/utils/validator.test.js deleted file mode 100755 index 7d400da..0000000 --- a/src/utils/validator.test.js +++ /dev/null @@ -1,34 +0,0 @@ -// validator.test -/* eslint-env jest */ - -import { readFileSync } from 'fs' - -import xml2obj from './xml2obj.js' - -import { validate, isRSS, isAtom } from './validator.js' - -test('test validate(well format xml)', async () => { - const xmlData = 'value' - const result = validate(xmlData) - expect(result).toBe(true) -}) - -test('test validate(bad format xml)', async () => { - const xmlData = 'value' - const result = validate(xmlData) - expect(result).toBe(false) -}) - -test('test validate(rss data)', async () => { - const xml = readFileSync('test-data/rss.xml', 'utf8') - const xmlData = xml2obj(xml) - expect(isRSS(xmlData)).toBe(true) - expect(isAtom(xmlData)).toBe(false) -}) - -test('test validate(atom data)', async () => { - const xml = readFileSync('test-data/atom.xml', 'utf8') - const xmlData = xml2obj(xml) - expect(isAtom(xmlData)).toBe(true) - expect(isRSS(xmlData)).toBe(false) -}) diff --git a/src/utils/xml2obj.js b/src/utils/xml2obj.js deleted file mode 100755 index 6ce8112..0000000 --- a/src/utils/xml2obj.js +++ /dev/null @@ -1,15 +0,0 @@ -// utils / xml2obj - -import { XMLParser } from 'fast-xml-parser/src/fxp.js' - -import { info } from './logger.js' - -export default (xml = '') => { - const options = { - ignoreAttributes: false - } - info('Parsing XML data...') - const parser = new XMLParser(options) - const jsonObj = parser.parse(xml) - return jsonObj -} diff --git a/src/utils/xmlparser.js b/src/utils/xmlparser.js new file mode 100755 index 0000000..afc8750 --- /dev/null +++ b/src/utils/xmlparser.js @@ -0,0 +1,26 @@ +// utils / xmlparser + +import { hasProperty, isString } from 'bellajs' + +import { XMLValidator, XMLParser } from 'fast-xml-parser' + +export const isRSS = (data = {}) => { + return hasProperty(data, 'rss') && hasProperty(data.rss, 'channel') +} + +export const isAtom = (data = {}) => { + return hasProperty(data, 'feed') && hasProperty(data.feed, 'entry') +} + +export const validate = (xml) => { + return (!isString(xml) || !xml.length) ? false : XMLValidator.validate(xml) === true +} + +export const xml2obj = (xml = '') => { + const options = { + ignoreAttributes: false + } + const parser = new XMLParser(options) + const jsonObj = parser.parse(xml) + return jsonObj +} diff --git a/src/utils/xmlparser.test.js b/src/utils/xmlparser.test.js new file mode 100755 index 0000000..e3aad84 --- /dev/null +++ b/src/utils/xmlparser.test.js @@ -0,0 +1,41 @@ +// xmlparser.test +/* eslint-env jest */ + +import { readFileSync } from 'fs' + +import { validate, isRSS, isAtom, xml2obj } from './xmlparser.js' + +describe('test methods from `xmlparser`', () => { + test('test validate(well format xml)', async () => { + const xmlData = 'value' + const result = validate(xmlData) + expect(result).toBe(true) + }) + + test('test validate(bad format xml)', async () => { + const xmlData = 'value' + const result = validate(xmlData) + expect(result).toBe(false) + }) + + test('test validate(standard rss content)', async () => { + const xml = readFileSync('test-data/rss-feed-standard.xml', 'utf8') + const xmlData = xml2obj(xml) + expect(isRSS(xmlData)).toBe(true) + expect(isAtom(xmlData)).toBe(false) + }) + + test('test validate(standard atom content)', async () => { + const xml = readFileSync('test-data/atom-feed-standard.xml', 'utf8') + const xmlData = xml2obj(xml) + expect(isAtom(xmlData)).toBe(true) + expect(isRSS(xmlData)).toBe(false) + }) + + test('test xml2obj(well format xml)', async () => { + const xmlData = 'value' + const result = xml2obj(xmlData) + expect(result).toBeInstanceOf(Object) + expect(result.xml).toBeInstanceOf(Object) + }) +}) diff --git a/test-data/atom-feed-standard-realworld.xml b/test-data/atom-feed-standard-realworld.xml new file mode 100644 index 0000000..50e2d2d --- /dev/null +++ b/test-data/atom-feed-standard-realworld.xml @@ -0,0 +1,283 @@ + + + https://news.google.com/atom?hl=en-US&gl=US&ceid=US:en + NFE/5.0 + Top stories - Google News + Google News + 2022-07-28T03:40:34.000000000Z + + Google Inc. + news-webmaster@google.com + https://news.google.com + + + + 2022 Google Inc. + + https://news.google.com/articles/CBMiWWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9zY2h1bWVyLW1hbmNoaW4tZGVhbC1idWlsZC1iYWNrLWJldHRlci9pbmRleC5odG1s0gFdaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9zY2h1bWVyLW1hbmNoaW4tZGVhbC1idWlsZC1iYWNrLWJldHRlci9pbmRleC5odG1s?oc=5 + In a major boost to Democrats, Manchin and Schumer announce deal for energy and health care bill - CNN + 2022-07-28T02:43:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9zY2h1bWVyLW1hbmNoaW4tZGVhbC1idWlsZC1iYWNrLWJldHRlci9pbmRleC5odG1s0gFdaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9zY2h1bWVyLW1hbmNoaW4tZGVhbC1idWlsZC1iYWNrLWJldHRlci9pbmRleC5odG1s?oc=5" target="_blank">In a major boost to Democrats, Manchin and Schumer announce deal for energy and health care bill</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3BvbGl0aWNzL21hbmNoaW4tc2NodW1lci1hZ3JlZS1yZWNvbmNpbGlhdGlvbi1kZWFsLWFmdGVyLW1vcmUtdGhhbi15ZWFyLXRhbGtz0gFpaHR0cHM6Ly93d3cuZm94bmV3cy5jb20vcG9saXRpY3MvbWFuY2hpbi1zY2h1bWVyLWFncmVlLXJlY29uY2lsaWF0aW9uLWRlYWwtYWZ0ZXItbW9yZS10aGFuLXllYXItdGFsa3MuYW1w?oc=5" target="_blank">Manchin, Schumer agree to vastly pared back version of Build Back Better</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9bGxYQzJhNVcwR2fSAQA?oc=5" target="_blank">Senate Democrats reach deal on Inflation Reduction Act</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvdXMvcG9saXRpY3MvbWFuY2hpbi1jbGltYXRlLXRheC1iaWxsLmh0bWzSAQA?oc=5" target="_blank">Manchin, in Reversal, Agrees to Quick Action on Climate and Tax Plan</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibWh0dHBzOi8vd3d3LmJsb29tYmVyZy5jb20vbmV3cy9hcnRpY2xlcy8yMDIyLTA3LTI3L3NlbmF0ZS1kZWFsLWluY2x1ZGVzLWV2LXRheC1jcmVkaXRzLXNvdWdodC1ieS10ZXNsYS10b3lvdGHSAQA?oc=5" target="_blank">Senate Deal Includes EV Tax Credits Sought by Tesla, Toyota</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg</font></li></ol> + + + https://news.google.com/articles/CBMidGh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9ncmluZXItd2hlbGFuLWJpZGVuLW9mZmVyLXZpa3Rvci1ib3V0LWV4Y2hhbmdlLXJ1c3NpYS1hcm1zLWRlYWxlci9pbmRleC5odG1s0gF4aHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9ncmluZXItd2hlbGFuLWJpZGVuLW9mZmVyLXZpa3Rvci1ib3V0LWV4Y2hhbmdlLXJ1c3NpYS1hcm1zLWRlYWxlci9pbmRleC5odG1s?oc=5 + CNN Exclusive: Biden administration offers convicted Russian arms dealer in exchange for Griner, Whelan - CNN + 2022-07-28T03:02:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9ncmluZXItd2hlbGFuLWJpZGVuLW9mZmVyLXZpa3Rvci1ib3V0LWV4Y2hhbmdlLXJ1c3NpYS1hcm1zLWRlYWxlci9pbmRleC5odG1s0gF4aHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9ncmluZXItd2hlbGFuLWJpZGVuLW9mZmVyLXZpa3Rvci1ib3V0LWV4Y2hhbmdlLXJ1c3NpYS1hcm1zLWRlYWxlci9pbmRleC5odG1s?oc=5" target="_blank">CNN Exclusive: Biden administration offers convicted Russian arms dealer in exchange for Griner, Whelan</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UE8zaXM2OFJWTWvSAQA?oc=5" target="_blank">U.S. offers deal to free Brittney Griner and Paul Whelan from Russia</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMicGh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3Nwb3J0cy91cy1vZmZlcnMtc3Vic3RhbnRpYWwtcHJvcG9zYWwtYnJpbmctYnJpdHRuZXktZ3JpbmVyLXBhdWwtd2hlbGFuLWhvbWUtZnJvbS1ydXNzaWHSAXRodHRwczovL3d3dy5mb3huZXdzLmNvbS9zcG9ydHMvdXMtb2ZmZXJzLXN1YnN0YW50aWFsLXByb3Bvc2FsLWJyaW5nLWJyaXR0bmV5LWdyaW5lci1wYXVsLXdoZWxhbi1ob21lLWZyb20tcnVzc2lhLmFtcA?oc=5" target="_blank">US offers 'substantial proposal' to bring Brittney Griner, Paul Whelan home from Russia</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WmptcmxGeVdiVm_SAQA?oc=5" target="_blank">US offers 'merchant of death' in exchange for Griner, Whelan</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQGh0dHBzOi8vd3d3Lm55dGltZXMuY29tL2xpdmUvMjAyMi8wNy8yNy93b3JsZC9ydXNzaWEtd2FyLXVrcmFpbmXSAQA?oc=5" target="_blank">Russia-Ukraine News: Live Updates</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li></ol> + + + https://news.google.com/articles/CAIiEIArqjZbv3V7kV3hMC0RhqEqFggEKg0IACoGCAowoPUEMKAjMLyu7wY?oc=5 + Covid Mask Mandate: Beverly Hills, 3 Other Local Cities Will Not Comply With L.A. Order - Deadline + 2022-07-28T01:13:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vZGVhZGxpbmUuY29tLzIwMjIvMDcvY292aWQtbWFzay1tYW5kYXRlLWJldmVybHktaGlsbHMtbG9zLWFuZ2VsZXMtMTIzNTA3OTU0OC_SAVlodHRwczovL2RlYWRsaW5lLmNvbS8yMDIyLzA3L2NvdmlkLW1hc2stbWFuZGF0ZS1iZXZlcmx5LWhpbGxzLWxvcy1hbmdlbGVzLTEyMzUwNzk1NDgvYW1wLw?oc=5" target="_blank">Covid Mask Mandate: Beverly Hills, 3 Other Local Cities Will Not Comply With L.A. Order</a>&nbsp;&nbsp;<font color="#6f6f6f">Deadline</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9SFJrcHFIQlFELWvSAQA?oc=5" target="_blank">Indoor mask mandate in LA County could be paused</a>&nbsp;&nbsp;<font color="#6f6f6f">FOX 11 Los Angeles</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9YTVhYmhnY0hlSzDSAQA?oc=5" target="_blank">Pasadena, Long Beach health officials say no to indoor mask mandate proposal</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS Los Angeles</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiP2h0dHBzOi8vd3d3LnNhY2JlZS5jb20vb3Bpbmlvbi9lZGl0b3JpYWxzL2FydGljbGUyNjM4NDAzNDcuaHRtbNIBAA?oc=5" target="_blank">Mask mandates remain the best way to defeat spread of virus</a>&nbsp;&nbsp;<font color="#6f6f6f">Sacramento Bee</font></li></ol> + + + https://news.google.com/articles/CAIiEF0VkJfNJVHVgsZgg5IxMv0qGQgEKhAIACoHCAow2Nb3CjDivdcCMP3ungY?oc=5 + Biden's call with Xi Jinping will focus on areas of U.S.-China cooperation, not just tension - CNBC + 2022-07-27T22:19:58.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMifGh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvYmlkZW5zLWNhbGwtd2l0aC14aS1qaW5waW5nLXdpbGwtaW5jbHVkZS1hcmVhcy1vZi11cy1jaGluYS1jb29wZXJhdGlvbi1ub3QtanVzdC10ZW5zaW9uLmh0bWzSAYABaHR0cHM6Ly93d3cuY25iYy5jb20vYW1wLzIwMjIvMDcvMjcvYmlkZW5zLWNhbGwtd2l0aC14aS1qaW5waW5nLXdpbGwtaW5jbHVkZS1hcmVhcy1vZi11cy1jaGluYS1jb29wZXJhdGlvbi1ub3QtanVzdC10ZW5zaW9uLmh0bWw?oc=5" target="_blank">Biden's call with Xi Jinping will focus on areas of U.S.-China cooperation, not just tension</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3dvcmxkL2NoaW5hLXdhcm5zLWZpcm0tYWJzb2x1dGUtcmVzcG9uc2Utc3BlYWtlci1wZWxvc2ktdmlzaXRzLXRhaXdhbtIBYWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3dvcmxkL2NoaW5hLXdhcm5zLWZpcm0tYWJzb2x1dGUtcmVzcG9uc2Utc3BlYWtlci1wZWxvc2ktdmlzaXRzLXRhaXdhbi5hbXA?oc=5" target="_blank">China warns of 'firm' and 'absolute' response if Speaker Pelosi visits Taiwan</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS9vcGluaW9ucy8yMDIyLzA3LzI3L3BlbG9zaS12aXNpdC10YWl3YW4tY2hpbmEtaW5mbHVlbmNlL9IBAA?oc=5" target="_blank">Opinion | Pelosi's visit to Taiwan shouldn't be dissuaded by China</a>&nbsp;&nbsp;<font color="#6f6f6f">The Washington Post</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMicmh0dHBzOi8vd3d3LmJsb29tYmVyZy5jb20vb3Bpbmlvbi9hcnRpY2xlcy8yMDIyLTA3LTI2L2JpZGVuLXMtdGFpd2FuLXN0cmF0ZWd5LWlzLWZsYXdlZC13aGV0aGVyLXBlbG9zaS1nb2VzLW9yLW5vdNIBAA?oc=5" target="_blank">Biden's Taiwan Strategy Is Flawed Whether Pelosi Goes or Not</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg</font></li></ol> + + + https://news.google.com/articles/CAIiELFgND4SOe0zunH-Q2dUhKMqFwgEKg8IACoHCAowjuuKAzCWrzwwloEY?oc=5 + Senate Passes $280 Billion Industrial Policy Bill to Counter China - The New York Times + 2022-07-28T01:08:21.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRmh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvdXMvcG9saXRpY3Mvc2VuYXRlLWNoaXBzLWNoaW5hLmh0bWzSAQA?oc=5" target="_blank">Senate Passes $280 Billion Industrial Policy Bill to Counter China</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9zZW5hdGUtdm90ZS1jaGlwcy1iaWxsLXNlbWljb25kdWN0b3ItbWFudWZhY3R1cmluZy9pbmRleC5odG1s0gFpaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9zZW5hdGUtdm90ZS1jaGlwcy1iaWxsLXNlbWljb25kdWN0b3ItbWFudWZhY3R1cmluZy9pbmRleC5odG1s?oc=5" target="_blank">Senate passes bipartisan bill investing $52 billion in US semiconductor production</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9enNlcGpoNmpBZ2_SAQA?oc=5" target="_blank">Senate passes bill to boost computer chip production in U.S.</a>&nbsp;&nbsp;<font color="#6f6f6f">13News Now</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMihAFodHRwczovL3d3dy5hemNlbnRyYWwuY29tL3N0b3J5L29waW5pb24vb3AtZWQvMjAyMi8wNy8yNy9jaGlwcy1hY3QtbWljcm9jaGlwLXNlbWljb25kdWN0b3ItbWFudWZhY3R1cmluZy1pbXBhY3QtYXJpem9uYS8xMDE2NDEyMzAwMi_SAQA?oc=5" target="_blank">CHIPS Act is great news for US supply chains, Arizona microchips</a>&nbsp;&nbsp;<font color="#6f6f6f">The Arizona Republic</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidWh0dHBzOi8vdGhlaGlsbC5jb20vb3Bpbmlvbi9jb25ncmVzcy1ibG9nLzM1NzQxMjAtcGFzcy10aGUtY2hpcHMtYWN0LXRvLXNlaXplLWFtZXJpY2FzLWJpZy1zZW1pY29uZHVjdG9yLW9wcG9ydHVuaXR5L9IBeWh0dHBzOi8vdGhlaGlsbC5jb20vb3Bpbmlvbi9jb25ncmVzcy1ibG9nLzM1NzQxMjAtcGFzcy10aGUtY2hpcHMtYWN0LXRvLXNlaXplLWFtZXJpY2FzLWJpZy1zZW1pY29uZHVjdG9yLW9wcG9ydHVuaXR5L2FtcC8?oc=5" target="_blank">Pass the CHIPS Act to seize America’s big semiconductor opportunity</a>&nbsp;&nbsp;<font color="#6f6f6f">The Hill</font></li></ol> + + + https://news.google.com/articles/CAIiEBiijZZ2ibQhmnwGCHH0xY4qGAgEKg8IACoHCAowjtSUCjC30XQwzqe5AQ?oc=5 + As Mega Millions hits $1 billion, past lottery winners show the money can bring heartache and pain - The Washington Post + 2022-07-27T23:05:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYWh0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS9uYXRpb24vMjAyMi8wNy8yNy9tZWdhLW1pbGxpb25zLWJpbGxpb24tamFja3BvdC13aW5uZXJzLWhhcHBpbmVzcy_SAQA?oc=5" target="_blank">As Mega Millions hits $1 billion, past lottery winners show the money can bring heartache and pain</a>&nbsp;&nbsp;<font color="#6f6f6f">The Washington Post</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibWh0dHBzOi8vd3d3LmZveGJ1c2luZXNzLmNvbS9lY29ub215L21lZ2EtbWlsbGlvbnMtamFja3BvdC1zd2VsbHMtb3Zlci0xYi1hZnRlci1uby13aW5uZXItbWFzc2l2ZS04MzBtLWRyYXdpbmfSAXFodHRwczovL3d3dy5mb3hidXNpbmVzcy5jb20vZWNvbm9teS9tZWdhLW1pbGxpb25zLWphY2twb3Qtc3dlbGxzLW92ZXItMWItYWZ0ZXItbm8td2lubmVyLW1hc3NpdmUtODMwbS1kcmF3aW5nLmFtcA?oc=5" target="_blank">Mega Millions jackpot swells to over $1B after no winner in massive $830M drawing</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox Business</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9d1FFZXlvQVlCRkXSAQA?oc=5" target="_blank">No Mega Millions jackpot, but 4 $1 million winners between NY, NJ</a>&nbsp;&nbsp;<font color="#6f6f6f">PIX11 News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMieGh0dHBzOi8vd3d3LmNoaWNhZ290cmlidW5lLmNvbS9uYXRpb24td29ybGQvY3QtYXVkLW53LW1lZ2EtbWlsbGlvbnMtcHJpemUtMjAyMjA3MjctbzRwb20yNTMzbmZ0ZGhkbHhqYTJ3N2luYXUtc3RvcnkuaHRtbNIBAA?oc=5" target="_blank">Confused by the huge Mega Millions prize? Here are some answers.</a>&nbsp;&nbsp;<font color="#6f6f6f">Chicago Tribune</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vZm94OC5jb20vbmV3cy8xYi1tZWdhLW1pbGxpb25zLWphY2twb3Qtc3VycHJpc2luZy10aGluZ3MteW91LWNvdWxkLWJ1eS_SAVNodHRwczovL2ZveDguY29tL25ld3MvMWItbWVnYS1taWxsaW9ucy1qYWNrcG90LXN1cnByaXNpbmctdGhpbmdzLXlvdS1jb3VsZC1idXkvYW1wLw?oc=5" target="_blank">$1B Mega Millions jackpot: Surprising things you could buy</a>&nbsp;&nbsp;<font color="#6f6f6f">WJW FOX 8 News Cleveland</font></li></ol> + + + https://news.google.com/articles/CBMicmh0dHBzOi8va3N0cC5jb20va3N0cC1uZXdzL3RvcC1uZXdzLzItZXgtbWlubmVhcG9saXMtb2ZmaWNlcnMtc2VudGVuY2VkLWZlZGVyYWwtcHJpc29uLXRvdS10aGFvLWotYWxleGFuZGVyLWt1ZW5nL9IBAA?oc=5 + 2 ex-Minneapolis officers sentenced to federal prison; 3.5 years for Thao, 3 years for Kueng - KSTP + 2022-07-27T19:58:57.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMicmh0dHBzOi8va3N0cC5jb20va3N0cC1uZXdzL3RvcC1uZXdzLzItZXgtbWlubmVhcG9saXMtb2ZmaWNlcnMtc2VudGVuY2VkLWZlZGVyYWwtcHJpc29uLXRvdS10aGFvLWotYWxleGFuZGVyLWt1ZW5nL9IBAA?oc=5" target="_blank">2 ex-Minneapolis officers sentenced to federal prison; 3.5 years for Thao, 3 years for Kueng</a>&nbsp;&nbsp;<font color="#6f6f6f">KSTP</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9dmh3N1p0d3hEc3fSAQA?oc=5" target="_blank">Two Former Minneapolis Officers Sentenced To Prison For Violating George Floyd's Rights</a>&nbsp;&nbsp;<font color="#6f6f6f">NBC News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMinAFodHRwczovL3d3dy5rYXJlMTEuY29tL2FydGljbGUvbmV3cy9sb2NhbC9nZW9yZ2UtZmxveWQvdGhhby1rdWVuZy1mZWRlcmFsLXNlbnRlbmNpbmctbWlubmVhcG9saXMtcG9saWNlLWdlb3JnZS1mbG95ZC84OS1iMDNkZDI4Ny1jMTA0LTQzOTItYjk1Yi01ZmQyODViNTFkOTHSAaABaHR0cHM6Ly93d3cua2FyZTExLmNvbS9hbXAvYXJ0aWNsZS9uZXdzL2xvY2FsL2dlb3JnZS1mbG95ZC90aGFvLWt1ZW5nLWZlZGVyYWwtc2VudGVuY2luZy1taW5uZWFwb2xpcy1wb2xpY2UtZ2VvcmdlLWZsb3lkLzg5LWIwM2RkMjg3LWMxMDQtNDM5Mi1iOTViLTVmZDI4NWI1MWQ5MQ?oc=5" target="_blank">Ex-officers Kueng, Thao sentenced to federal prison for violating George Floyd's civil rights</a>&nbsp;&nbsp;<font color="#6f6f6f">KARE11.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WlVYX1B4cFNidzTSAQA?oc=5" target="_blank">Legal analyst discusses sentencing of ex-MPD officers Kueng, Thao</a>&nbsp;&nbsp;<font color="#6f6f6f">KARE 11</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiigFodHRwczovL3d3dy50aGVkYWlseWJlYXN0LmNvbS9leC1taW5uZWFwb2xpcy1jb3Atai1hbGV4YW5kZXIta3VlbmctZ2V0cy10aHJlZS15ZWFycy1mb3ItZmFpbGluZy10by1zdG9wLWRlcmVrLWNoYXV2aW4ta2lsbGluZy1nZW9yZ2UtZmxveWTSAQA?oc=5" target="_blank">Cops Who Failed to Stop Chauvin From Killing George Floyd Sentenced to Several Years in Prison</a>&nbsp;&nbsp;<font color="#6f6f6f">The Daily Beast</font></li></ol> + + + https://news.google.com/articles/CAIiEBYP5iNjn1vjvsEgGARIgXUqFwgEKg8IACoHCAownaG1AjClySAwy9Y4?oc=5 + Fed unleashes another big rate hike in bid to curb inflation - WRAL News + 2022-07-27T22:30:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiW2h0dHBzOi8vd3d3LndyYWwuY29tL2ZlZC11bmxlYXNoZXMtYW5vdGhlci1iaWctcmF0ZS1oaWtlLWluLWJpZC10by1jdXJiLWluZmxhdGlvbi8yMDM5MTgzNC_SAWdodHRwczovL3d3dy53cmFsLmNvbS9mZWQtdW5sZWFzaGVzLWFub3RoZXItYmlnLXJhdGUtaGlrZS1pbi1iaWQtdG8tY3VyYi1pbmZsYXRpb24vMjAzOTE4MzQvP3ZlcnNpb249YW1w?oc=5" target="_blank">Fed unleashes another big rate hike in bid to curb inflation</a>&nbsp;&nbsp;<font color="#6f6f6f">WRAL News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vZmluYW5jZS55YWhvby5jb20vbmV3cy9mZWRlcmFsLXJlc2VydmUtaW50ZXJlc3QtcmF0ZXMtZm9tYy1tb25ldGFyeS1wb2xpY3ktZGVjaXNpb24tanVseS0yMDIyLTE0MDU0MDI2NS5odG1s0gF8aHR0cHM6Ly9maW5hbmNlLnlhaG9vLmNvbS9hbXBodG1sL25ld3MvZmVkZXJhbC1yZXNlcnZlLWludGVyZXN0LXJhdGVzLWZvbWMtbW9uZXRhcnktcG9saWN5LWRlY2lzaW9uLWp1bHktMjAyMi0xNDA1NDAyNjUuaHRtbA?oc=5" target="_blank">Federal Reserve raises interest rates by 0.75%, matching June's historic move</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo Finance</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MEdZMnB6UWJELW_SAQA?oc=5" target="_blank">U.S. stocks rally after Fed rate hike</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvZmVkLWludGVyZXN0LXJhdGUtaGlrZS13aGF0LXdpbGwtYmUtbW9yZS1leHBlbnNpdmUuaHRtbNIBW2h0dHBzOi8vd3d3LmNuYmMuY29tL2FtcC8yMDIyLzA3LzI3L2ZlZC1pbnRlcmVzdC1yYXRlLWhpa2Utd2hhdC13aWxsLWJlLW1vcmUtZXhwZW5zaXZlLmh0bWw?oc=5" target="_blank">The Fed just raised interest rates by another 0.75%—here are 5 things that will be more expensive</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVmh0dHBzOi8vd3d3LnJldXRlcnMuY29tL21hcmtldHMvdXMvZmVkLWhpa2VzLXJhdGVzLWFub3RoZXItNzUtYmFzaXMtcG9pbnRzLTIwMjItMDctMjcv0gEA?oc=5" target="_blank">Reactions after Fed hikes rates by another 75 basis points</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li></ol> + + + https://news.google.com/articles/CBMiamh0dHBzOi8vd3d3Lm5iY3BoaWxhZGVscGhpYS5jb20vbmV3cy9sb2NhbC8yNS1taWxsaW9uLWxhd3N1aXQtZmlsZWQtb3Zlci1zZXNhbWUtcGxhY2UtYWNjdXNhdGlvbnMvMzMxNzc2OS_SAXBodHRwczovL3d3dy5uYmNwaGlsYWRlbHBoaWEuY29tL25ld3MvbG9jYWwvMjUtbWlsbGlvbi1sYXdzdWl0LWZpbGVkLW92ZXItc2VzYW1lLXBsYWNlLWFjY3VzYXRpb25zLzMzMTc3NjkvP2FtcD0x?oc=5 + $25 Million Lawsuit Filed Over Sesame Place Accusations - NBC 10 Philadelphia + 2022-07-28T01:14:32.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiamh0dHBzOi8vd3d3Lm5iY3BoaWxhZGVscGhpYS5jb20vbmV3cy9sb2NhbC8yNS1taWxsaW9uLWxhd3N1aXQtZmlsZWQtb3Zlci1zZXNhbWUtcGxhY2UtYWNjdXNhdGlvbnMvMzMxNzc2OS_SAXBodHRwczovL3d3dy5uYmNwaGlsYWRlbHBoaWEuY29tL25ld3MvbG9jYWwvMjUtbWlsbGlvbi1sYXdzdWl0LWZpbGVkLW92ZXItc2VzYW1lLXBsYWNlLWFjY3VzYXRpb25zLzMzMTc3NjkvP2FtcD0x?oc=5" target="_blank">$25 Million Lawsuit Filed Over Sesame Place Accusations</a>&nbsp;&nbsp;<font color="#6f6f6f">NBC 10 Philadelphia</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy91cy9waGlsYWRlbHBoaWEtc2Vhd29ybGQtc2VzYW1lLXBsYWNlLXN1aXQtcmVhai9pbmRleC5odG1s0gFdaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy91cy9waGlsYWRlbHBoaWEtc2Vhd29ybGQtc2VzYW1lLXBsYWNlLXN1aXQtcmVhai9pbmRleC5odG1s?oc=5" target="_blank">Family sues SeaWorld's Sesame Place Philadelphia for alleged racist interaction</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vd3d3LmlucXVpcmVyLmNvbS9jb2x1bW5pc3RzL3Nlc2FtZS1wbGFjZS1yb3NpdGEtcmFjaXNtLTIwMjIwNzI3Lmh0bWzSAVtodHRwczovL3d3dy5pbnF1aXJlci5jb20vY29sdW1uaXN0cy9zZXNhbWUtcGxhY2Utcm9zaXRhLXJhY2lzbS0yMDIyMDcyNy5odG1sP291dHB1dFR5cGU9YW1w?oc=5" target="_blank">Sesame Place staff needs more than just DEI training</a>&nbsp;&nbsp;<font color="#6f6f6f">The Philadelphia Inquirer</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiswFodHRwczovL3d3dy5idWNrc2NvdW50eWNvdXJpZXJ0aW1lcy5jb20vc3RvcnkvbmV3cy9sb2NhbC8yMDIyLzA3LzI3L3Nlc2FtZS1wbGFjZS1yb3NpdGEtam9kaS1icm93bi1yYWNlLWJsYWNrLW1pZGRsZXRvd24tYnVja3MtY291bnR5LWxhbmdob3JuZS1kaXNjcmltaW5hdGlvbi1sYXdzdWl0LzY1Mzg0NjcwMDA3L9IBAA?oc=5" target="_blank">Maryland dad sues Sesame Place alleging characters snubbed his child</a>&nbsp;&nbsp;<font color="#6f6f6f">Bucks County Courier Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWmh0dHBzOi8vNmFiYy5jb20vc2VzYW1lLXBsYWNlLWxhd3N1aXQtdmlyYWwtdmlkZW8tcm9zaXRhLWNoYXJhY3Rlci1yYWNpc20tY2xhaW1zLzEyMDc3MTE4L9IBXmh0dHBzOi8vNmFiYy5jb20vYW1wL3Nlc2FtZS1wbGFjZS1sYXdzdWl0LXZpcmFsLXZpZGVvLXJvc2l0YS1jaGFyYWN0ZXItcmFjaXNtLWNsYWltcy8xMjA3NzExOC8?oc=5" target="_blank">Law firm files class action lawsuit against Sesame Place following claims of racial bias at Langhorne, Pennsylvania park</a>&nbsp;&nbsp;<font color="#6f6f6f">WPVI-TV</font></li></ol> + + + https://news.google.com/articles/CAIiEPJbnPy9JLSqafimuC3liOQqFwgEKg8IACoHCAowjuuKAzCWrzwwloEY?oc=5 + With Roe Gone, Republicans Quarrel Over How Far to Push Abortion Bans - The New York Times + 2022-07-27T22:20:31.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiO2h0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvdXMvaW5kaWFuYS1hYm9ydGlvbi5odG1s0gEA?oc=5" target="_blank">With Roe Gone, Republicans Quarrel Over How Far to Push Abortion Bans</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9bjNMY0YzdFNWckXSAQA?oc=5" target="_blank">Signs of the Times | Protestors fight for their side at Indiana statehouse</a>&nbsp;&nbsp;<font color="#6f6f6f">WTHR</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMigQFodHRwczovL3d3dy5pbmR5c3Rhci5jb20vc3Rvcnkvb3Bpbmlvbi8yMDIyLzA3LzI2L3doeS1pbmRpYW5hLWxlZ2lzbGF0b3JzLXNob3VsZC1saXN0ZW4tdG8tYWxsLXZvaWNlcy1hYm91dC1hYm9ydGlvbi82NTM4MTQxNDAwNy_SAQA?oc=5" target="_blank">Why Indiana legislators should listen to all voices about abortion</a>&nbsp;&nbsp;<font color="#6f6f6f">IndyStar</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9anVvLUt1QkpnemfSAQA?oc=5" target="_blank">Legal experts, doctors raise concerns about Indiana abortion bill</a>&nbsp;&nbsp;<font color="#6f6f6f">FOX59 News</font></li></ol> + + + https://news.google.com/articles/CAIiEDecZ4kgm3XIr9d3zcEa1A4qFggEKg4IACoGCAowl6p7MN-zCTDlkko?oc=5 + Hundreds of protesters storm Iraq parliament in support of cleric Moqtada al-Sadr - The Guardian + 2022-07-28T01:47:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMif2h0dHBzOi8vd3d3LnRoZWd1YXJkaWFuLmNvbS93b3JsZC8yMDIyL2p1bC8yOC9odW5kcmVkcy1vZi1wcm90ZXN0ZXJzLXN0b3JtLWlyYXEtcGFybGlhbWVudC1pbi1zdXBwb3J0LW9mLWNsZXJpYy1tb3F0YWRhLWFsLXNhZHLSAX9odHRwczovL2FtcC50aGVndWFyZGlhbi5jb20vd29ybGQvMjAyMi9qdWwvMjgvaHVuZHJlZHMtb2YtcHJvdGVzdGVycy1zdG9ybS1pcmFxLXBhcmxpYW1lbnQtaW4tc3VwcG9ydC1vZi1jbGVyaWMtbW9xdGFkYS1hbC1zYWRy?oc=5" target="_blank">Hundreds of protesters storm Iraq parliament in support of cleric Moqtada al-Sadr</a>&nbsp;&nbsp;<font color="#6f6f6f">The Guardian</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WWhMVkxDZGtEbmfSAQA?oc=5" target="_blank">Hundreds Of Protesters Storm Iraqi Parliament</a>&nbsp;&nbsp;<font color="#6f6f6f">NBC News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWmh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9taWRkbGVlYXN0L2lyYXEtcHJvdGVzdHMtYmFnaGRhZC1ncmVlbi16b25lLWludGwvaW5kZXguaHRtbNIBXmh0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvbWlkZGxlZWFzdC9pcmFxLXByb3Rlc3RzLWJhZ2hkYWQtZ3JlZW4tem9uZS1pbnRsL2luZGV4Lmh0bWw?oc=5" target="_blank">Iraqi protesters break into parliament denouncing the nomination of new premier</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZWh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vbmV3cy8yMDIyLzcvMjcvaXJhcWktcHJvdGVzdGVycy1zdG9ybS1wYXJsaWFtZW50LW11cXRhZGEtYWwtc2Fkci1ncmVlbi16b25l0gFpaHR0cHM6Ly93d3cuYWxqYXplZXJhLmNvbS9hbXAvbmV3cy8yMDIyLzcvMjcvaXJhcWktcHJvdGVzdGVycy1zdG9ybS1wYXJsaWFtZW50LW11cXRhZGEtYWwtc2Fkci1ncmVlbi16b25l?oc=5" target="_blank">Iraqi protesters storm the parliament in Baghdad’s Green Zone</a>&nbsp;&nbsp;<font color="#6f6f6f">Al Jazeera English</font></li></ol> + + + https://news.google.com/articles/CBMiR2h0dHBzOi8vYWJjNy5jb20vbW9ua2V5cy1hdHRhY2stamFwYW4tdG9reW8tYW5pbWFscy15YW1hZ3VjaGkvMTIwNzY5MzEv0gFLaHR0cHM6Ly9hYmM3LmNvbS9hbXAvbW9ua2V5cy1hdHRhY2stamFwYW4tdG9reW8tYW5pbWFscy15YW1hZ3VjaGkvMTIwNzY5MzEv?oc=5 + Japanese monkeys stealing babies, clawing at flesh, Yamaguchi city officials say - KABC-TV + 2022-07-28T02:01:14.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiR2h0dHBzOi8vYWJjNy5jb20vbW9ua2V5cy1hdHRhY2stamFwYW4tdG9reW8tYW5pbWFscy15YW1hZ3VjaGkvMTIwNzY5MzEv0gFLaHR0cHM6Ly9hYmM3LmNvbS9hbXAvbW9ua2V5cy1hdHRhY2stamFwYW4tdG9reW8tYW5pbWFscy15YW1hZ3VjaGkvMTIwNzY5MzEv?oc=5" target="_blank">Japanese monkeys stealing babies, clawing at flesh, Yamaguchi city officials say</a>&nbsp;&nbsp;<font color="#6f6f6f">KABC-TV</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiUWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3dvcmxkL2phcGFuZXNlLWNpdHktdW5kZXItYXR0YWNrLXZpb2xlbnQtbW9ua2V5cy1zby1zbWFydNIBVWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3dvcmxkL2phcGFuZXNlLWNpdHktdW5kZXItYXR0YWNrLXZpb2xlbnQtbW9ua2V5cy1zby1zbWFydC5hbXA?oc=5" target="_blank">Japanese city under attack by violent monkeys: 'They are so smart'</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MWw2cHhma0RKbVXSAQA?oc=5" target="_blank">Japanese city alarmed by biting, clawing, attacking monkeys</a>&nbsp;&nbsp;<font color="#6f6f6f">WGN News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiamh0dHBzOi8vd3d3LnRoZWRhaWx5YmVhc3QuY29tL2phcGFuZXNlLW1vbmtleS1nYW5nLWxlYWRlci1raWxsZWQtYWZ0ZXItZG96ZW5zLW9mLXZpY2lvdXMtYXR0YWNrcy1vbi1sb2NhbHPSAQA?oc=5" target="_blank">Japanese Monkey Gang Leader Killed After Dozens of Vicious Attacks on Locals</a>&nbsp;&nbsp;<font color="#6f6f6f">The Daily Beast</font></li></ol> + + + https://news.google.com/articles/CBMid2h0dHBzOi8vd3d3LnJldXRlcnMuY29tL2J1c2luZXNzL2Flcm9zcGFjZS1kZWZlbnNlL3J1c3NpYS1uYXNhLXN0aWNraW5nLXdpdGgtc3BhY2Utc3RhdGlvbi11bnRpbC1sZWFzdC0yMDI4LTIwMjItMDctMjcv0gEA?oc=5 + Russia tells NASA space station pullout less imminent than indicated earlier - Reuters + 2022-07-28T01:38:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMid2h0dHBzOi8vd3d3LnJldXRlcnMuY29tL2J1c2luZXNzL2Flcm9zcGFjZS1kZWZlbnNlL3J1c3NpYS1uYXNhLXN0aWNraW5nLXdpdGgtc3BhY2Utc3RhdGlvbi11bnRpbC1sZWFzdC0yMDI4LTIwMjItMDctMjcv0gEA?oc=5" target="_blank">Russia tells NASA space station pullout less imminent than indicated earlier</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9aERnMU8xMU5Ed0XSAQA?oc=5" target="_blank">Russia says it will withdraw from the International Space Station after 2024</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS90ZWNobm9sb2d5LzIwMjIvMDcvMjcvbmFzYS1zcGFjZS1zdGF0aW9uLXJ1c3NpYS_SAQA?oc=5" target="_blank">NASA hopes to keep ISS operating despite Russia pullout threat</a>&nbsp;&nbsp;<font color="#6f6f6f">The Washington Post</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9cVg1NExnUHRxa0HSAQA?oc=5" target="_blank">'It's an opportunity for NASA': Russia announces ISS withdrawal</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vcHJvZ3JhbS9pbnNpZGUtc3RvcnkvMjAyMi83LzI3L3doYXRzLXRoZS1mdXR1cmUtb2YtdGhlLWludGVybmF0aW9uYWwtc3BhY2Utc3RhdGlvbtIBcGh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vYW1wL3Byb2dyYW0vaW5zaWRlLXN0b3J5LzIwMjIvNy8yNy93aGF0cy10aGUtZnV0dXJlLW9mLXRoZS1pbnRlcm5hdGlvbmFsLXNwYWNlLXN0YXRpb24?oc=5" target="_blank">What’s the future of the International Space Station?</a>&nbsp;&nbsp;<font color="#6f6f6f">Al Jazeera English</font></li></ol> + + + https://news.google.com/articles/CAIiEArgWE-LFcdeHMMjBFueoVgqGQgEKhAIACoHCAowjsP7CjCSpPQCMM_b5QU?oc=5 + Ukraine warns Kremlin to 'retreat or be annihilated' in Kherson; US pushing deal to free Griner: Live updates - USA TODAY + 2022-07-27T22:52:30.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXWh0dHBzOi8vd3d3LnVzYXRvZGF5LmNvbS9zdG9yeS9uZXdzL3dvcmxkLzIwMjIvMDcvMjcvdWtyYWluZS1ydXNzaWEtbGl2ZS11cGRhdGVzLzEwMTYwODM0MDAyL9IBAA?oc=5" target="_blank">Ukraine warns Kremlin to 'retreat or be annihilated' in Kherson; US pushing deal to free Griner: Live updates</a>&nbsp;&nbsp;<font color="#6f6f6f">USA TODAY</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3dvcmxkL3VrcmFpbmUtdGFrZXMtb3V0LWtleS1icmlkZ2UtZGVzdHJveWluZy1ydXNzaWFuLXBsYW5zLXNvdXRoLWFkdmFuY2VtZW500gFpaHR0cHM6Ly93d3cuZm94bmV3cy5jb20vd29ybGQvdWtyYWluZS10YWtlcy1vdXQta2V5LWJyaWRnZS1kZXN0cm95aW5nLXJ1c3NpYW4tcGxhbnMtc291dGgtYWR2YW5jZW1lbnQuYW1w?oc=5" target="_blank">Ukraine takes out key bridge 'destroying' Russian plans for south 'advancement'</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9c1lEbFhqejR3c1nSAQA?oc=5" target="_blank">Ukraine Targets Bridge Used By Russian Forces For Supplies</a>&nbsp;&nbsp;<font color="#6f6f6f">9NEWS</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vbmV3cy55YWhvby5jb20vdWtyYWluaWFuLWFybWVkLWZvcmNlcy1jb25maXJtLWtoZXJzb24tMDYxNzAxMzg0Lmh0bWzSAVRodHRwczovL25ld3MueWFob28uY29tL2FtcGh0bWwvdWtyYWluaWFuLWFybWVkLWZvcmNlcy1jb25maXJtLWtoZXJzb24tMDYxNzAxMzg0Lmh0bWw?oc=5" target="_blank">Ukrainian Armed Forces confirm that Kherson bridge destroyed in high-precision strike</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQGh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvcnVzc2lhLXVrcmFpbmUtbGl2ZS11cGRhdGVzLmh0bWzSAURodHRwczovL3d3dy5jbmJjLmNvbS9hbXAvMjAyMi8wNy8yNy9ydXNzaWEtdWtyYWluZS1saXZlLXVwZGF0ZXMuaHRtbA?oc=5" target="_blank">Ukrainian ports prepare to restart grain shipments; U.S. makes offer for release of detained Americans Griner and Whelan</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li></ol> + + + https://news.google.com/articles/CAIiEIkLoxWAvg44XOMMDAa2fLkqFggEKg4IACoGCAow3O8nMMqOBjD38Ak?oc=5 + Spirit and Frontier Airlines throw out merger agreement - The Verge + 2022-07-27T22:09:45.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZ2h0dHBzOi8vd3d3LnRoZXZlcmdlLmNvbS8yMDIyLzcvMjcvMjMyODEyOTAvc3Bpcml0LWFpcmxpbmVzLWZyb250aWVyLXRocm93LW91dC1tZXJnZXItYWdyZWVtZW50LWpldGJsdWXSAQA?oc=5" target="_blank">Spirit and Frontier Airlines throw out merger agreement</a>&nbsp;&nbsp;<font color="#6f6f6f">The Verge</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMicmh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvc3Bpcml0LWFpcmxpbmVzLWZyb250aWVyLXRlcm1pbmF0ZS1kZWFsLXRoYXQtd2FzLW1hcnJlZC1ieS1qZXRibHVlcy1yaXZhbC1iaWQuaHRtbNIBdmh0dHBzOi8vd3d3LmNuYmMuY29tL2FtcC8yMDIyLzA3LzI3L3NwaXJpdC1haXJsaW5lcy1mcm9udGllci10ZXJtaW5hdGUtZGVhbC10aGF0LXdhcy1tYXJyZWQtYnktamV0Ymx1ZXMtcml2YWwtYmlkLmh0bWw?oc=5" target="_blank">Spirit ends merger agreement with Frontier, continues takeover talks with JetBlue</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiP2h0dHBzOi8vd3d3LmZ0LmNvbS9jb250ZW50LzEwNTQyZTVkLWYyN2UtNDIxMi05MzhkLTNiNjk1NmM2ZWIwOdIBAA?oc=5" target="_blank">Live news updates: Ford reaffirms outlook as sales rebound, but acknowledges inflationary pressures</a>&nbsp;&nbsp;<font color="#6f6f6f">Financial Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LmJsb29tYmVyZy5jb20vb3Bpbmlvbi9hcnRpY2xlcy8yMDIyLTA3LTI3L3NwaXJpdC1mb3JjZWQtdG8tbGlzdGVuLXRvLWludmVzdG9ycy1hbmQtZHVtcC1mcm9udGllctIBAA?oc=5" target="_blank">Spirit Forced to Listen to Investors and Dump Frontier</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9bDVLZXhMdzJMQlnSAQA?oc=5" target="_blank">Spirit Airlines shareholders weigh merger with Frontier as JetBlue pitches rival offer</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li></ol> + + + https://news.google.com/articles/CAIiENk8Cc_LTKBszuz0oTt15doqGQgEKhAIACoHCAowzpuGCzCQ9YMDMOT8twY?oc=5 + QCOM Stock: Qualcomm Beats Targets But Misses With Outlook - Investor's Business Daily + 2022-07-27T21:40:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZGh0dHBzOi8vd3d3LmludmVzdG9ycy5jb20vbmV3cy90ZWNobm9sb2d5L3Fjb20tc3RvY2stcXVhbGNvbW0tYmVhdHMtdGFyZ2V0cy1idXQtbWlzc2VzLXdpdGgtb3V0bG9vay_SAQA?oc=5" target="_blank">QCOM Stock: Qualcomm Beats Targets But Misses With Outlook</a>&nbsp;&nbsp;<font color="#6f6f6f">Investor's Business Daily</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQ2h0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvcXVhbGNvbW0tcWNvbS1lYXJuaW5ncy1xMy0yMDIyLmh0bWzSAUdodHRwczovL3d3dy5jbmJjLmNvbS9hbXAvMjAyMi8wNy8yNy9xdWFsY29tbS1xY29tLWVhcm5pbmdzLXEzLTIwMjIuaHRtbA?oc=5" target="_blank">Qualcomm sales rise 37% despite 'challenging macroeconomic environment'</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9N3BIRnUwVWhnTkXSAQA?oc=5" target="_blank">Qualcomm revenues beat, but company issues weak fourth quarter outlook</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC Television</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiY2h0dHBzOi8vd3d3LmZveGJ1c2luZXNzLmNvbS9tYXJrZXRzL3F1YWxjb21tLXJldmVudWUtZm9yZWNhc3QtZGlzYXBwb2ludHMtY29vbGluZy1zbWFydHBob25lLWRlbWFuZNIBZ2h0dHBzOi8vd3d3LmZveGJ1c2luZXNzLmNvbS9tYXJrZXRzL3F1YWxjb21tLXJldmVudWUtZm9yZWNhc3QtZGlzYXBwb2ludHMtY29vbGluZy1zbWFydHBob25lLWRlbWFuZC5hbXA?oc=5" target="_blank">Qualcomm revenue forecast disappoints on cooling smartphone demand</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox Business</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiW2h0dHBzOi8vZmluYW5jZS55YWhvby5jb20vbmV3cy9xdWFsY29tbS1yZXZlbnVlLWZvcmVjYXN0LWRpc2FwcG9pbnRzLWNvb2xpbmctMjAwMzA4NTE1Lmh0bWzSAWNodHRwczovL2ZpbmFuY2UueWFob28uY29tL2FtcGh0bWwvbmV3cy9xdWFsY29tbS1yZXZlbnVlLWZvcmVjYXN0LWRpc2FwcG9pbnRzLWNvb2xpbmctMjAwMzA4NTE1Lmh0bWw?oc=5" target="_blank">Qualcomm warns of sales hit from cooling smartphone demand</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo Finance</font></li></ol> + + + https://news.google.com/articles/CCAiC1B3czZQSHRSdndJmAEB?oc=5 + Ford Earnings Top Estimates as Prices Cliimb - Bloomberg Markets and Finance + 2022-07-27T21:45:26.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UHdzNlBIdFJ2d0nSAQA?oc=5" target="_blank">Ford Earnings Top Estimates as Prices Cliimb</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg Markets and Finance</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiPGh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvZm9yZC1mLWVhcm5pbmdzLXEyLTIwMjIuaHRtbNIBQGh0dHBzOi8vd3d3LmNuYmMuY29tL2FtcC8yMDIyLzA3LzI3L2ZvcmQtZi1lYXJuaW5ncy1xMi0yMDIyLmh0bWw?oc=5" target="_blank">Ford beats expectations and raises dividend as company sells more of its top models</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UC02aGlhLU9WSFnSAQA?oc=5" target="_blank">Ford stock tops earnings expectations, revenue exceeds $40 billion</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo Finance</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMib2h0dHBzOi8vd3d3LmF1dG9uZXdzLmNvbS9hdXRvbWFrZXJzLXN1cHBsaWVycy9mb3JkLWVhcm5pbmdzLXEyLW5ldC1pbmNvbWUtcmlzZXMtMTktNjY3LW1pbGxpb24tcmV2ZW51ZS1qdW1wcy01MNIBAA?oc=5" target="_blank">Ford generates $667 million in Q2 net income as revenue jumps 50%</a>&nbsp;&nbsp;<font color="#6f6f6f">Automotive News</font></li></ol> + + + https://news.google.com/articles/CAIiEFHcL-rLs1JhVTbpVyjmy7EqGQgEKhAIACoHCAow4uzwCjCF3bsCMIrOrwM?oc=5 + Fed Watchers Say Markets Got It All Wrong on Powell 'Pivot' - Bloomberg + 2022-07-27T22:09:58.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LmJsb29tYmVyZy5jb20vbmV3cy9hcnRpY2xlcy8yMDIyLTA3LTI3L2ZlZC13YXRjaGVycy1zYXktbWFya2V0cy1nb3QtaXQtYWxsLXdyb25nLW9uLXBvd2VsbC1waXZvdNIBAA?oc=5" target="_blank">Fed Watchers Say Markets Got It All Wrong on Powell 'Pivot'</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMifGh0dHBzOi8vd3d3Lm1hcmtldHdhdGNoLmNvbS9zdG9yeS9zdXJwcmlzZS1ob3ctdGhlLXN0b2NrLW1hcmtldC1oYXMtcmVhY3RlZC1vbi1lYWNoLWZlZC1kZWNpc2lvbi1kYXktc2luY2UtbWFyY2gtMTE2NTg5MzM5OTPSAYABaHR0cHM6Ly93d3cubWFya2V0d2F0Y2guY29tL2FtcC9zdG9yeS9zdXJwcmlzZS1ob3ctdGhlLXN0b2NrLW1hcmtldC1oYXMtcmVhY3RlZC1vbi1lYWNoLWZlZC1kZWNpc2lvbi1kYXktc2luY2UtbWFyY2gtMTE2NTg5MzM5OTM?oc=5" target="_blank">Surprise? How the stock market has reacted on day of each Fed rate hike in 2022</a>&nbsp;&nbsp;<font color="#6f6f6f">MarketWatch</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYmh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9idXNpbmVzcy9uaWdodGNhcC1mZWQtaW50ZXJlc3QtcmF0ZXMtaW5mbGF0aW9uLXJlY2Vzc2lvbi9pbmRleC5odG1s0gFmaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9idXNpbmVzcy9uaWdodGNhcC1mZWQtaW50ZXJlc3QtcmF0ZXMtaW5mbGF0aW9uLXJlY2Vzc2lvbi9pbmRleC5odG1s?oc=5" target="_blank">The Fed is bushwhacking through uncharted territory</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYWh0dHBzOi8vdGhlaGlsbC5jb20vb3Bpbmlvbi9maW5hbmNlLzM1NzM5NzQtdGhlLXByb2JsZW0td2l0aC1hLXBlcnNpc3RlbnRseS1sYXRlLWZlZGVyYWwtcmVzZXJ2ZS_SAWVodHRwczovL3RoZWhpbGwuY29tL29waW5pb24vZmluYW5jZS8zNTczOTc0LXRoZS1wcm9ibGVtLXdpdGgtYS1wZXJzaXN0ZW50bHktbGF0ZS1mZWRlcmFsLXJlc2VydmUvYW1wLw?oc=5" target="_blank">The problem with a persistently late Federal Reserve</a>&nbsp;&nbsp;<font color="#6f6f6f">The Hill</font></li></ol> + + + https://news.google.com/articles/CAIiEC7CI6gl_LXLHdv-RPApV2AqFwgEKg4IACoGCAow3O8nMMqOBjCkztQD?oc=5 + Now all Google Nest cameras can stream video to your TV - The Verge + 2022-07-28T00:05:10.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiW2h0dHBzOi8vd3d3LnRoZXZlcmdlLmNvbS8yMDIyLzcvMjcvMjMyODE1ODAvZ29vZ2xlLW5lc3QtY2FtLWNocm9tZWNhc3QtZ29vZ2xlLXR2LWxpdmUtdmlkZW_SAQA?oc=5" target="_blank">Now all Google Nest cameras can stream video to your TV</a>&nbsp;&nbsp;<font color="#6f6f6f">The Verge</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQGh0dHBzOi8vOXRvNWdvb2dsZS5jb20vMjAyMi8wNy8yNy9jaHJvbWVjYXN0LWdvb2dsZS10di1uZXN0LWNhbS_SAURodHRwczovLzl0bzVnb29nbGUuY29tLzIwMjIvMDcvMjcvY2hyb21lY2FzdC1nb29nbGUtdHYtbmVzdC1jYW0vYW1wLw?oc=5" target="_blank">Chromecast with Google TV finally supports streaming live video from new Nest Cams, Doorbell</a>&nbsp;&nbsp;<font color="#6f6f6f">9to5Google</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRmh0dHBzOi8vd3d3LmVuZ2FkZ2V0LmNvbS9uZXN0LWNocm9tZWNhc3Qtd2l0aC1nb29nbGUtdHYtMjEwMDAxMzQ2Lmh0bWzSAUpodHRwczovL3d3dy5lbmdhZGdldC5jb20vYW1wL25lc3QtY2hyb21lY2FzdC13aXRoLWdvb2dsZS10di0yMTAwMDEzNDYuaHRtbA?oc=5" target="_blank">Nest cameras can now, at long last, livestream to Chromecast with Google TV</a>&nbsp;&nbsp;<font color="#6f6f6f">Engadget</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vd3d3LmRyb2lkLWxpZmUuY29tLzIwMjIvMDcvMjcvc3RyZWFtLW5lc3QtY2FtLWZlZWRzLXJpZ2h0LXRvLXlvdXItZ29vZ2xlLXR2L9IBWGh0dHBzOi8vd3d3LmRyb2lkLWxpZmUuY29tLzIwMjIvMDcvMjcvc3RyZWFtLW5lc3QtY2FtLWZlZWRzLXJpZ2h0LXRvLXlvdXItZ29vZ2xlLXR2L2FtcC8?oc=5" target="_blank">Stream Nest Cam Feeds Right to Your Google TV</a>&nbsp;&nbsp;<font color="#6f6f6f">Droid Life</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiSGh0dHBzOi8vd3d3LmFuZHJvaWRwb2xpY2UuY29tL25lc3QtbGl2ZS1mZWVkcy1jaHJvbWVjYXN0LXdpdGgtZ29vZ2xlLXR2L9IBTGh0dHBzOi8vd3d3LmFuZHJvaWRwb2xpY2UuY29tL25lc3QtbGl2ZS1mZWVkcy1jaHJvbWVjYXN0LXdpdGgtZ29vZ2xlLXR2L2FtcC8?oc=5" target="_blank">Embrace your inner Big Brother with Nest live feeds on Chromecast with Google TV</a>&nbsp;&nbsp;<font color="#6f6f6f">Android Police</font></li></ol> + + + https://news.google.com/articles/CBMic2h0dHBzOi8vd3d3LnB1c2hzcXVhcmUuY29tL2ZlYXR1cmVzL3JlYWN0aW9uLW1ldGEtcXVlc3QtMnMtcHJpY2UtaGlrZS13aWxsLWhhdmUtcHN2cjItcmVsaWV2ZWQtb3ItcnViYmluZy1pdHMtaGFuZHPSAQA?oc=5 + Reaction: Meta Quest 2's Price Hike Will Have PSVR2 Relieved or Rubbing Its Hands - Push Square + 2022-07-27T13:00:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMic2h0dHBzOi8vd3d3LnB1c2hzcXVhcmUuY29tL2ZlYXR1cmVzL3JlYWN0aW9uLW1ldGEtcXVlc3QtMnMtcHJpY2UtaGlrZS13aWxsLWhhdmUtcHN2cjItcmVsaWV2ZWQtb3ItcnViYmluZy1pdHMtaGFuZHPSAQA?oc=5" target="_blank">Reaction: Meta Quest 2's Price Hike Will Have PSVR2 Relieved or Rubbing Its Hands</a>&nbsp;&nbsp;<font color="#6f6f6f">Push Square</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWGh0dHBzOi8vbGlmZWhhY2tlci5jb20vaWYteW91cmUtcGxhbm5pbmctdG8tYnV5LWEtbWV0YS1xdWVzdC0yLWJldHRlci1kby1pdC1mLTE4NDkzMzg2NjLSAVxodHRwczovL2xpZmVoYWNrZXIuY29tL2lmLXlvdXJlLXBsYW5uaW5nLXRvLWJ1eS1hLW1ldGEtcXVlc3QtMi1iZXR0ZXItZG8taXQtZi0xODQ5MzM4NjYyL2FtcA?oc=5" target="_blank">If You're Planning to Buy a Meta Quest 2, Better Do It Fast</a>&nbsp;&nbsp;<font color="#6f6f6f">Lifehacker</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMimQFodHRwczovL3d3dy5iZW56aW5nYS5jb20vYW5hbHlzdC1yYXRpbmdzL2FuYWx5c3QtY29sb3IvMjIvMDcvMjgyMTg3NDgvbWV0YXMtcXVlc3QtMi1oZWFkc2V0LWhpa2UtbGVhdmVzLWFuYWx5c3Qtd29ycmllZC1hYm91dC10aGUtZ2Vhci1sb3NpbmctY3JpdGljYWwtY2_SAS1odHRwczovL3d3dy5iZW56aW5nYS5jb20vYW1wL2NvbnRlbnQvMjgyMTg3NDg?oc=5" target="_blank">Meta's Quest 2 Headset Price Hike Leaves Analyst Worried About The Gear Losing 'Critical Competitive Adva</a>&nbsp;&nbsp;<font color="#6f6f6f">Benzinga</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiOWh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vb3Bpbmlvbi9tZXRhLXF1ZXN0LTItcHJpY2UtaGlrZdIBAA?oc=5" target="_blank">Meta Quest 2 price hike is pure greed — and bad for VR</a>&nbsp;&nbsp;<font color="#6f6f6f">Tom's Guide</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vd3d3Lmlnbi5jb20vYXJ0aWNsZXMveGJveC13aXJlbGVzcy1jb250cm9sbGVyLW1ldGEtcXVlc3QtMi1kYWlseS1kZWFscy03MjcyMtIBWmh0dHBzOi8vd3d3Lmlnbi5jb20vYXJ0aWNsZXMveGJveC13aXJlbGVzcy1jb250cm9sbGVyLW1ldGEtcXVlc3QtMi1kYWlseS1kZWFscy03MjcyMj9hbXA9MQ?oc=5" target="_blank">Daily Deals: Xbox Wireless Controller, Xbox Series X, Meta Quest 2, and More - IGN</a>&nbsp;&nbsp;<font color="#6f6f6f">IGN</font></li></ol> + + + https://news.google.com/articles/CAIiEH8Km8sswzM3JKFhOPKs64YqGQgEKhAIACoHCAowyoD5CjD5z-ACMM_rvwU?oc=5 + Likely camera sensors for Pixel 7, 7 Pro, and Pixel tablet uncovered in code - 9to5Google + 2022-07-26T17:13:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRGh0dHBzOi8vOXRvNWdvb2dsZS5jb20vMjAyMi8wNy8yNi9waXhlbC03LXByby10YWJsZXQtY2FtZXJhLXNlbnNvcnMv0gFIaHR0cHM6Ly85dG81Z29vZ2xlLmNvbS8yMDIyLzA3LzI2L3BpeGVsLTctcHJvLXRhYmxldC1jYW1lcmEtc2Vuc29ycy9hbXAv?oc=5" target="_blank">Likely camera sensors for Pixel 7, 7 Pro, and Pixel tablet uncovered in code</a>&nbsp;&nbsp;<font color="#6f6f6f">9to5Google</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiS2h0dHBzOi8vd2NjZnRlY2guY29tL3RoZS1nb29nbGUtcGl4ZWwtNy1wcm8tdXNlcy0zLXNhbXN1bmctaXNvY2VsbC1jYW1lcmFzL9IBT2h0dHBzOi8vd2NjZnRlY2guY29tL3RoZS1nb29nbGUtcGl4ZWwtNy1wcm8tdXNlcy0zLXNhbXN1bmctaXNvY2VsbC1jYW1lcmFzL2FtcC8?oc=5" target="_blank">The Google Pixel 7 Pro Uses 3 Samsung ISOCELL Cameras</a>&nbsp;&nbsp;<font color="#6f6f6f">Wccftech</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiemh0dHBzOi8vd3d3LmdzbWFyZW5hLmNvbS9nb29nbGVfcGl4ZWxfN183X3Byb19waXhlbF90YWJsZXRfYW5kX2ZvbGRhYmxlX3NtYXJ0cGhvbmVfY2FtZXJhX3NlbnNvcnNfdW5jb3ZlcmVkLW5ld3MtNTUyMDAucGhw0gF3aHR0cHM6Ly9tLmdzbWFyZW5hLmNvbS9nb29nbGVfcGl4ZWxfN183X3Byb19waXhlbF90YWJsZXRfYW5kX2ZvbGRhYmxlX3NtYXJ0cGhvbmVfY2FtZXJhX3NlbnNvcnNfdW5jb3ZlcmVkLWFtcC01NTIwMC5waHA?oc=5" target="_blank">Google Pixel 7, 7 Pro, Pixel Tablet and Pixel foldable camera sensors uncovered - GSMArena.com news</a>&nbsp;&nbsp;<font color="#6f6f6f">GSMArena.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMic2h0dHBzOi8vd3d3LnBvY2tldC1saW50LmNvbS9waG9uZXMvbmV3cy9nb29nbGUvMTYyMDEzLWdvb2dsZS1waXhlbC03LWFuZC1waXhlbC03LXByby1jYW1lcmEtc2Vuc29yLXNwZWNzLWFyZS1sZWFrZWTSAXtodHRwczovL3d3dy5wb2NrZXQtbGludC5jb20vcGhvbmVzL25ld3MvZ29vZ2xlLzE2MjAxMy1nb29nbGUtcGl4ZWwtNy1hbmQtcGl4ZWwtNy1wcm8tY2FtZXJhLXNlbnNvci1zcGVjcy1hcmUtbGVha2VkLmFtcGh0bWw?oc=5" target="_blank">Google Pixel 7 and Pixel 7 Pro camera sensor specs have leaked</a>&nbsp;&nbsp;<font color="#6f6f6f">Pocket-lint</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXmh0dHBzOi8vd3d3LmxhcHRvcG1hZy5jb20vbmV3cy9waXhlbC03LWNhbWVyYS1kZXRhaWxzLWV4cG9zZWQtYW5kLWl0LWNvbWVzLXdpdGgtZmFtaWxpYXItc3BlY3PSAQA?oc=5" target="_blank">Pixel 7 camera details exposed — and it comes with familiar specs</a>&nbsp;&nbsp;<font color="#6f6f6f">Laptop Mag</font></li></ol> + + + https://news.google.com/articles/CAIiEJMjT-6tTGbXLH1Sr6K9pYYqFggEKg0IACoGCAows4UBMMAaMNPRtQY?oc=5 + CarPlay wallpaper options expand in iOS 16 beta 4, download images here - 9to5Mac + 2022-07-27T19:03:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiOGh0dHBzOi8vOXRvNW1hYy5jb20vMjAyMi8wNy8yNy9jYXJwbGF5LXdhbGxwYXBlci1pb3MtMTYv0gE8aHR0cHM6Ly85dG81bWFjLmNvbS8yMDIyLzA3LzI3L2NhcnBsYXktd2FsbHBhcGVyLWlvcy0xNi9hbXAv?oc=5" target="_blank">CarPlay wallpaper options expand in iOS 16 beta 4, download images here</a>&nbsp;&nbsp;<font color="#6f6f6f">9to5Mac</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vd3d3LnRoZXZlcmdlLmNvbS8yMDIyLzcvMjcvMjMyODExMTAvYXBwbGUtaW1lc3NhZ2UtZWRpdC1oaXN0b3J5LWlvcy0xNtIBAA?oc=5" target="_blank">Apple's latest iOS 16 beta ensures you can't hide your mistakes with an edit</a>&nbsp;&nbsp;<font color="#6f6f6f">The Verge</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MkV0MDFyT29YaU3SAQA?oc=5" target="_blank">Everything NEW in iOS 16 Beta 4! Live Activities, Editing Messages, & More!</a>&nbsp;&nbsp;<font color="#6f6f6f">AppleInsider</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTWh0dHBzOi8vd3d3Lm1hY3J1bW9ycy5jb20vMjAyMi8wNy8yNy9hcHBsZS1zZWVkcy1pb3MtMTYtYmV0YS00LXRvLWRldmVsb3BlcnMv0gEA?oc=5" target="_blank">Apple Seeds Fourth Betas of iOS 16 and iPadOS 16 to Developers</a>&nbsp;&nbsp;<font color="#6f6f6f">MacRumors</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRmh0dHBzOi8vd3d3LnRoZXZlcmdlLmNvbS8yMzI3OTI4My9hcHBsZS1ob21la2l0LWhvbWUtYXBwLWlvczE2LXByZXZpZXfSAQA?oc=5" target="_blank">iOS 16 Home app preview: What’s new in Apple’s HomeKit smart home app</a>&nbsp;&nbsp;<font color="#6f6f6f">The Verge</font></li></ol> + + + https://news.google.com/articles/CBMiXGh0dHBzOi8vd3d3LmNic25ld3MuY29tL25ld3MvdG9ueS1kb3ctZGVhZC1hZ2UtNzctYWN0b3Itd2FsbHktY2xlYXZlci1vbi1sZWF2ZS1pdC10by1iZWF2ZXIv0gFgaHR0cHM6Ly93d3cuY2JzbmV3cy5jb20vYW1wL25ld3MvdG9ueS1kb3ctZGVhZC1hZ2UtNzctYWN0b3Itd2FsbHktY2xlYXZlci1vbi1sZWF2ZS1pdC10by1iZWF2ZXIv?oc=5 + Tony Dow, known for playing Wally Cleaver on "Leave It to Beaver," dead at 77 - CBS News + 2022-07-27T23:14:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXGh0dHBzOi8vd3d3LmNic25ld3MuY29tL25ld3MvdG9ueS1kb3ctZGVhZC1hZ2UtNzctYWN0b3Itd2FsbHktY2xlYXZlci1vbi1sZWF2ZS1pdC10by1iZWF2ZXIv0gFgaHR0cHM6Ly93d3cuY2JzbmV3cy5jb20vYW1wL25ld3MvdG9ueS1kb3ctZGVhZC1hZ2UtNzctYWN0b3Itd2FsbHktY2xlYXZlci1vbi1sZWF2ZS1pdC10by1iZWF2ZXIv?oc=5" target="_blank">Tony Dow, known for playing Wally Cleaver on "Leave It to Beaver," dead at 77</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9lbnRlcnRhaW5tZW50L3RvbnktZG93LW9iaXQvaW5kZXguaHRtbNIBSWh0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvZW50ZXJ0YWlubWVudC90b255LWRvdy1vYml0L2luZGV4Lmh0bWw?oc=5" target="_blank">Tony Dow, 'Leave It to Beaver' star, has died</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiUmh0dHBzOi8vd3d3LmZveG5ld3MuY29tL2VudGVydGFpbm1lbnQvdG9ueS1kb3ctbGVhdmUtYmVhdmVyLXN0YXItZGVhZC1iZXR0ZXItcGxhY2XSAVZodHRwczovL3d3dy5mb3huZXdzLmNvbS9lbnRlcnRhaW5tZW50L3RvbnktZG93LWxlYXZlLWJlYXZlci1zdGFyLWRlYWQtYmV0dGVyLXBsYWNlLmFtcA?oc=5" target="_blank">Tony Dow, 'Leave It to Beaver' star, dead at 77, son confirms: 'He is in a better place'</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WEJkbGhTNVp1RzjSAQA?oc=5" target="_blank">'Leave it to Beaver' actor Tony Dow dies at 77 | USA TODAY</a>&nbsp;&nbsp;<font color="#6f6f6f">USA TODAY</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L2xlYXZlLWl0LXRvLWJlYXZlci1zdGFyLXRvbnktZG93LWRlYWQtYXQtNzctMi_SAVBodHRwczovL255cG9zdC5jb20vMjAyMi8wNy8yNy9sZWF2ZS1pdC10by1iZWF2ZXItc3Rhci10b255LWRvdy1kZWFkLWF0LTc3LTIvYW1wLw?oc=5" target="_blank">'Leave It to Beaver' star Tony Dow dead at 77 after premature announcement</a>&nbsp;&nbsp;<font color="#6f6f6f">New York Post </font></li></ol> + + + https://news.google.com/articles/CBMiU2h0dHBzOi8vd3d3LnlhaG9vLmNvbS9saWZlc3R5bGUvaW5zdGFncmFtLWhlYWQtcmVzcG9uZHMta3lsaWUtamVubmVyLTE5MDk1NjQ5NC5odG1s0gFbaHR0cHM6Ly93d3cueWFob28uY29tL2FtcGh0bWwvbGlmZXN0eWxlL2luc3RhZ3JhbS1oZWFkLXJlc3BvbmRzLWt5bGllLWplbm5lci0xOTA5NTY0OTQuaHRtbA?oc=5 + Instagram’s head responds to Kylie Jenner, Kim Kardashian sharing petition for app to ‘stop trying to be TikTok’ - Yahoo Life + 2022-07-27T20:48:37.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiU2h0dHBzOi8vd3d3LnlhaG9vLmNvbS9saWZlc3R5bGUvaW5zdGFncmFtLWhlYWQtcmVzcG9uZHMta3lsaWUtamVubmVyLTE5MDk1NjQ5NC5odG1s0gFbaHR0cHM6Ly93d3cueWFob28uY29tL2FtcGh0bWwvbGlmZXN0eWxlL2luc3RhZ3JhbS1oZWFkLXJlc3BvbmRzLWt5bGllLWplbm5lci0xOTA5NTY0OTQuaHRtbA?oc=5" target="_blank">Instagram’s head responds to Kylie Jenner, Kim Kardashian sharing petition for app to ‘stop trying to be TikTok’</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo Life</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVmh0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS90ZWNobm9sb2d5LzIwMjIvMDcvMjcvaW5zdGFncmFtLXZpZGVvLXNoaWZ0LWthcmRhc2hpYW4v0gEA?oc=5" target="_blank">Instagram is shifting to videos. Users, including the Kardashians, aren't happy.</a>&nbsp;&nbsp;<font color="#6f6f6f">The Washington Post</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WFFrTTRBeDlKOWvSAQA?oc=5" target="_blank">Instagram CEO RESPONDS After Kardashian-Jenner Backlash | E! News</a>&nbsp;&nbsp;<font color="#6f6f6f">E! News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibmh0dHBzOi8vd3d3Lmh1ZmZwb3N0LmNvbS9lbnRyeS9raW0ta2FyZGFzaGlhbi1reWxpZS1qZW5uZXItaW5zdGFncmFtLWNoYW5nZXMtdGlrdG9rX25fNjJlMGFkYzJlNGIwYWFkNThkMjBhYzU50gFyaHR0cHM6Ly93d3cuaHVmZnBvc3QuY29tL2VudHJ5L2tpbS1rYXJkYXNoaWFuLWt5bGllLWplbm5lci1pbnN0YWdyYW0tY2hhbmdlcy10aWt0b2tfbl82MmUwYWRjMmU0YjBhYWQ1OGQyMGFjNTkvYW1w?oc=5" target="_blank">Kim Kardashian, Kylie Jenner Blast Instagram Changes: Stop Trying To Be TikTok</a>&nbsp;&nbsp;<font color="#6f6f6f">HuffPost</font></li></ol> + + + https://news.google.com/articles/CAIiENgie7gT5LS3UaR8HyGbuHYqGQgEKhAIACoHCAowmID5CjDdtOACMLzWtAU?oc=5 + Neil Patrick Harris got final approval of d--k pic used in new show 'Uncoupled' - Page Six + 2022-07-27T20:49:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZ2h0dHBzOi8vcGFnZXNpeC5jb20vMjAyMi8wNy8yNy9uZWlsLXBhdHJpY2staGFycmlzLWdvdC1hcHByb3ZhbC1vZi1kaWNrLXBpYy1mb3ItaGlzLW5ldy1zaG93LXVuY291cGxlZC_SAWtodHRwczovL3BhZ2VzaXguY29tLzIwMjIvMDcvMjcvbmVpbC1wYXRyaWNrLWhhcnJpcy1nb3QtYXBwcm92YWwtb2YtZGljay1waWMtZm9yLWhpcy1uZXctc2hvdy11bmNvdXBsZWQvYW1wLw?oc=5" target="_blank">Neil Patrick Harris got final approval of d--k pic used in new show 'Uncoupled'</a>&nbsp;&nbsp;<font color="#6f6f6f">Page Six</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZkxNdXBBa1NJa0nSAQA?oc=5" target="_blank">Neil Patrick Harris On Getting A Glimpse Of Today's Dating Scene In Show “Uncoupled” | The View</a>&nbsp;&nbsp;<font color="#6f6f6f">The View</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiX2h0dHBzOi8vdHZsaW5lLmNvbS8yMDIyLzA3LzI3L3VuY291cGxlZC1yZXZpZXctbmV0ZmxpeC1uZWlsLXBhdHJpY2staGFycmlzLWdheS1yb21hbnRpYy1jb21lZHkv0gFjaHR0cHM6Ly90dmxpbmUuY29tLzIwMjIvMDcvMjcvdW5jb3VwbGVkLXJldmlldy1uZXRmbGl4LW5laWwtcGF0cmljay1oYXJyaXMtZ2F5LXJvbWFudGljLWNvbWVkeS9hbXAv?oc=5" target="_blank">Uncoupled Review: Neil Patrick Harris Exposes Himself (Emotionally) in Netflix's Gay Romantic Comedy</a>&nbsp;&nbsp;<font color="#6f6f6f">TVLine</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMia2h0dHBzOi8vcGVvcGxlLmNvbS90di9uZWlsLXBhdHJpY2staGFycmlzLXNheXMtaGlzLTE4LXllYXItcmVsYXRpb25zaGlwLXdpdGgtZGF2aWQtYnVydGthLWlzLWFsbC1pdmUta25vd24v0gF0aHR0cHM6Ly9wZW9wbGUuY29tL3R2L25laWwtcGF0cmljay1oYXJyaXMtc2F5cy1oaXMtMTgteWVhci1yZWxhdGlvbnNoaXAtd2l0aC1kYXZpZC1idXJ0a2EtaXMtYWxsLWl2ZS1rbm93bi8_YW1wPXRydWU?oc=5" target="_blank">Neil Patrick Harris on Playing Newly Uncoupled When Love for Husband David Burtka Is 'All I've Known'</a>&nbsp;&nbsp;<font color="#6f6f6f">PEOPLE</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vdmFyaWV0eS5jb20vMjAyMi90di9yZXZpZXdzL3VuY291cGxlZC1uZWlsLXBhdHJpY2staGFycmlzLXJldmlldy0xMjM1MzE4ODczL9IBWGh0dHBzOi8vdmFyaWV0eS5jb20vMjAyMi90di9yZXZpZXdzL3VuY291cGxlZC1uZWlsLXBhdHJpY2staGFycmlzLXJldmlldy0xMjM1MzE4ODczL2FtcC8?oc=5" target="_blank">‘Uncoupled’ Is a Surprisingly Sour Neil Patrick Harris Breakup Story: TV Review</a>&nbsp;&nbsp;<font color="#6f6f6f">Variety</font></li></ol> + + + https://news.google.com/articles/CAIiEMEMKxsrsp4-rYiJammu6GsqGQgEKhAIACoHCAow9MSGCzCKpYQDMK-o7wY?oc=5 + Britney Spears Wins: Judge Denies Jamie Spears’ Motion To Compel Pop Star’s Deposition - Rolling Stone + 2022-07-27T22:49:38.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiaWh0dHBzOi8vd3d3LnJvbGxpbmdzdG9uZS5jb20vbXVzaWMvbXVzaWMtbmV3cy9icml0bmV5LXNwZWFycy1jb25zZXJ2YXRvcnNoaXAtamFtaWUtbW90aW9uLWRlbmllZC0xMzg4NTg3L9IBbWh0dHBzOi8vd3d3LnJvbGxpbmdzdG9uZS5jb20vbXVzaWMvbXVzaWMtbmV3cy9icml0bmV5LXNwZWFycy1jb25zZXJ2YXRvcnNoaXAtamFtaWUtbW90aW9uLWRlbmllZC0xMzg4NTg3L2FtcC8?oc=5" target="_blank">Britney Spears Wins: Judge Denies Jamie Spears’ Motion To Compel Pop Star’s Deposition</a>&nbsp;&nbsp;<font color="#6f6f6f">Rolling Stone</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiaGh0dHBzOi8vd3d3LnRoZWRhaWx5YmVhc3QuY29tL2JyaXRuZXktc3BlYXJzLWNhbi1za2lwLWRlcG9zaXRpb24tYnktZGFkLWphbWllLXNwZWFycy1sYXd5ZXJzLWp1ZGdlLXJ1bGVz0gEA?oc=5" target="_blank">Britney Can Skip Deposition by Dad's Lawyers, Judge Rules</a>&nbsp;&nbsp;<font color="#6f6f6f">The Daily Beast</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZmh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9lbnRlcnRhaW5tZW50L2JyaXRuZXktc3BlYXJzLW5vdC1kZXBvc2VkLWNvbnNlcnZhdG9yc2hpcC1kYWQvaW5kZXguaHRtbNIBamh0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvZW50ZXJ0YWlubWVudC9icml0bmV5LXNwZWFycy1ub3QtZGVwb3NlZC1jb25zZXJ2YXRvcnNoaXAtZGFkL2luZGV4Lmh0bWw?oc=5" target="_blank">Judge rules Britney Spears will not have to sit for deposition in ongoing legal battle with her father</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li></ol> + + + https://news.google.com/articles/CBMiUGh0dHBzOi8vd3d3Lm1sYnRyYWRlcnVtb3JzLmNvbS8yMDIyLzA3L3lhbmtlZXMtdG8tYWNxdWlyZS1hbmRyZXctYmVuaW50ZW5kaS5odG1s0gEA?oc=5 + Yankees Acquire Andrew Benintendi From Royals - MLB Trade Rumors + 2022-07-28T03:32:32.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiUGh0dHBzOi8vd3d3Lm1sYnRyYWRlcnVtb3JzLmNvbS8yMDIyLzA3L3lhbmtlZXMtdG8tYWNxdWlyZS1hbmRyZXctYmVuaW50ZW5kaS5odG1s0gEA?oc=5" target="_blank">Yankees Acquire Andrew Benintendi From Royals</a>&nbsp;&nbsp;<font color="#6f6f6f">MLB Trade Rumors</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMikQFodHRwczovL3d3dy5lc3BuLmNvbS9tbGIvc3RvcnkvXy9pZC8zNDMwNDgyMS9uZXcteW9yay15YW5rZWVzLWZpbmFsaXppbmctZGVhbC1hY3F1aXJlLW91dGZpZWxkZXItYW5kcmV3LWJlbmludGVuZGkta2Fuc2FzLWNpdHktcm95YWxzLXNvdXJjZXMtc2F50gGeAWh0dHBzOi8vd3d3LmVzcG4uY29tL21sYi9zdG9yeS9fL2lkLzM0MzA0ODIxL25ldy15b3JrLXlhbmtlZXMtZmluYWxpemluZy1kZWFsLWFjcXVpcmUtb3V0ZmllbGRlci1hbmRyZXctYmVuaW50ZW5kaS1rYW5zYXMtY2l0eS1yb3lhbHMtc291cmNlcy1zYXk_cGxhdGZvcm09YW1w?oc=5" target="_blank">New York Yankees acquire All-Star outfielder Andrew Benintendi from the Kansas City Royals</a>&nbsp;&nbsp;<font color="#6f6f6f">ESPN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L3lhbmtlZXMtdHJhZGUtZm9yLXJveWFscy1vdXRmaWVsZGVyLWFuZHJldy1iZW5pbnRlbmRpL9IBWGh0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L3lhbmtlZXMtdHJhZGUtZm9yLXJveWFscy1vdXRmaWVsZGVyLWFuZHJldy1iZW5pbnRlbmRpL2FtcC8?oc=5" target="_blank">Yankees trade for Royals outfielder Andrew Benintendi</a>&nbsp;&nbsp;<font color="#6f6f6f">New York Post </font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vd3d3LmthbnNhc2NpdHkuY29tL3Nwb3J0cy9tbGIva2Fuc2FzLWNpdHktcm95YWxzL2FydGljbGUyNjM5MDU4NTcuaHRtbNIBTmh0dHBzOi8vYW1wLmthbnNhc2NpdHkuY29tL3Nwb3J0cy9tbGIva2Fuc2FzLWNpdHktcm95YWxzL2FydGljbGUyNjM5MDU4NTcuaHRtbA?oc=5" target="_blank">KC Royals trade Andrew Benintendi to New York Yankees. Here’s who they’re getting</a>&nbsp;&nbsp;<font color="#6f6f6f">Kansas City Star</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiOGh0dHBzOi8vd3d3Lm1sYi5jb20vbmV3cy9hbmRyZXctYmVuaW50ZW5kaS15YW5rZWVzLXRyYWRl0gEA?oc=5" target="_blank">Andrew Benintendi traded to Yankees</a>&nbsp;&nbsp;<font color="#6f6f6f">MLB.com</font></li></ol> + + + https://news.google.com/articles/CBMic2h0dHBzOi8vaG9vcHNoeXBlLmNvbS9saXN0cy9uZXRzLWNlbHRpY3MtcnVtb3JzLWtldmluLWR1cmFudC1reXJpZS1pcnZpbmctamF5bGVuLWJyb3duLW1hcmN1cy1zbWFydC1ncmFudC13aWxsaWFtcy_SAQA?oc=5 + Nets and Celtics rumors: Kevin Durant, Kyrie Irving, Jaylen Brown, Marcus Smart, Grant Williams - Hoops Hype + 2022-07-28T01:21:49.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMic2h0dHBzOi8vaG9vcHNoeXBlLmNvbS9saXN0cy9uZXRzLWNlbHRpY3MtcnVtb3JzLWtldmluLWR1cmFudC1reXJpZS1pcnZpbmctamF5bGVuLWJyb3duLW1hcmN1cy1zbWFydC1ncmFudC13aWxsaWFtcy_SAQA?oc=5" target="_blank">Nets and Celtics rumors: Kevin Durant, Kyrie Irving, Jaylen Brown, Marcus Smart, Grant Williams</a>&nbsp;&nbsp;<font color="#6f6f6f">Hoops Hype</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMimgFodHRwczovL3d3dy5lc3BuLmNvbS9uYmEvc3RvcnkvXy9pZC8zNDMwMDIyOC9ib3N0b24tY2VsdGljcy1qYXlzb24tdGF0dW0tcmVzcG9uZGluZy1rZXZpbi1kdXJhbnQtdHJhZGUtc3BlY3VsYXRpb24tc2F5cy1sb3ZlLW91ci10ZWFtLXJlbHVjdGFudC1wdXQtZ20taGF00gGnAWh0dHBzOi8vd3d3LmVzcG4uY29tL25iYS9zdG9yeS9fL2lkLzM0MzAwMjI4L2Jvc3Rvbi1jZWx0aWNzLWpheXNvbi10YXR1bS1yZXNwb25kaW5nLWtldmluLWR1cmFudC10cmFkZS1zcGVjdWxhdGlvbi1zYXlzLWxvdmUtb3VyLXRlYW0tcmVsdWN0YW50LXB1dC1nbS1oYXQ_cGxhdGZvcm09YW1w?oc=5" target="_blank">Boston Celtics' Jayson Tatum, responding to Kevin Durant trade speculation, says 'I love our team,' doesn't wear GM hat</a>&nbsp;&nbsp;<font color="#6f6f6f">ESPN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vYmxlYWNoZXJyZXBvcnQuY29tL2FydGljbGVzLzEwMDQzNDMxLWhlLXdvbnQtZm9yZ2V0LXRoaXMtYXJlLWNlbHRpY3MtZnVtYmxpbmctcmVsYXRpb25zaGlwLXdpdGgtamF5bGVuLWJyb3du0gGEAWh0dHBzOi8vc3luZGljYXRpb24uYmxlYWNoZXJyZXBvcnQuY29tL2FtcC8xMDA0MzQzMS1oZS13b250LWZvcmdldC10aGlzLWFyZS1jZWx0aWNzLWZ1bWJsaW5nLXJlbGF0aW9uc2hpcC13aXRoLWpheWxlbi1icm93bi5hbXAuaHRtbA?oc=5" target="_blank">'He Won't Forget This': Are Celtics Fumbling Relationship with Jaylen Brown?</a>&nbsp;&nbsp;<font color="#6f6f6f">Bleacher Report</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vY2VsdGljc3dpcmUudXNhdG9kYXkuY29tLzIwMjIvMDcvMjcvbmJhLWJvc3Rvbi1jZWx0aWNzLWpiLWtkLW5ldHMtcG92L9IBAA?oc=5" target="_blank">Should the Brooklyn Nets be interested in trading Kevin Durant to the Boston Celtics for Jaylen Brown?</a>&nbsp;&nbsp;<font color="#6f6f6f">Celtics Wire</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMi3AFodHRwczovL2ZhZGVhd2F5d29ybGQubmV0L25iYS1tZWRpYS9jaGFybGVzLWJhcmtsZXktZ2l2ZXMtaGlzLXRha2Utb24td2h5LWtldmluLWR1cmFudC1yZXF1ZXN0ZWQtYS10cmFkZS1pLWRvbnQta25vdy13aGF0cy1nb2luZy1vbi1iZWhpbmQtdGhlLXNjZW5lcy1idXQtaXQtc291bmRzLWxpa2UtaGUtanVzdC1oYWQtZW5vdWdoLW9mLWt5cmllLXRoYXRzLW15LWhvbmVzdC1vcGluaW9u0gHhAWh0dHBzOi8vZmFkZWF3YXl3b3JsZC5uZXQvLmFtcC9uYmEtbWVkaWEvY2hhcmxlcy1iYXJrbGV5LWdpdmVzLWhpcy10YWtlLW9uLXdoeS1rZXZpbi1kdXJhbnQtcmVxdWVzdGVkLWEtdHJhZGUtaS1kb250LWtub3ctd2hhdHMtZ29pbmctb24tYmVoaW5kLXRoZS1zY2VuZXMtYnV0LWl0LXNvdW5kcy1saWtlLWhlLWp1c3QtaGFkLWVub3VnaC1vZi1reXJpZS10aGF0cy1teS1ob25lc3Qtb3Bpbmlvbg?oc=5" target="_blank">Charles Barkley Gives His Take On Why Kevin Durant Requested A Trade: "I Don't Know What's Going On Behind The Scenes But It Sounds Like He Just Had Enough Of Kyrie, That's My Honest Opinion."</a>&nbsp;&nbsp;<font color="#6f6f6f">Fadeaway World</font></li></ol> + + + https://news.google.com/articles/CAIiENHgypkdWJ31Z5QdX6VB2KYqGAgEKg8IACoHCAowhK-LAjD4ySww-9S0BQ?oc=5 + Mets sweep Yankees with walk-off win after Max Scherzer dominates - New York Post + 2022-07-28T02:37:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L21ldHMtZ2V0LXdhbGstb2ZmLXdpbi10by10b3AteWFua2Vlcy1zd2VlcC1zdWJ3YXktc2VyaWVzL9IBW2h0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L21ldHMtZ2V0LXdhbGstb2ZmLXdpbi10by10b3AteWFua2Vlcy1zd2VlcC1zdWJ3YXktc2VyaWVzL2FtcC8?oc=5" target="_blank">Mets sweep Yankees with walk-off win after Max Scherzer dominates</a>&nbsp;&nbsp;<font color="#6f6f6f">New York Post </font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9emZmdTdSV2hOcGfSAQA?oc=5" target="_blank">Yankees vs. Mets Game Highlights (7/26/22) | MLB Highlights</a>&nbsp;&nbsp;<font color="#6f6f6f">MLB</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMilQFodHRwczovL3d3dy5tc24uY29tL2VuLXVzL3Nwb3J0cy9tbGIvc3Vid2F5LXNlcmllcy1oYXMtbmV3LXlvcmstYmFzZWJhbGwtZmFucy1kcmVhbWluZy1vZi1hLXlhbmtlZXMtbWV0cy13b3JsZC1zZXJpZXMtb3Bpbmlvbi9hci1BQTEwMWxhej9saT1CQjE1bXM1cdIBAA?oc=5" target="_blank">Subway Series has New York baseball fans dreaming of a Yankees-Mets World Series | Opinion</a>&nbsp;&nbsp;<font color="#6f6f6f">msnNOW</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L3lhbmtlZXMtdnMtbWV0cy1zdWJ3YXktc2VyaWVzLTIwMjItZ2FtZS0yLWxpdmUtdXBkYXRlcy_SAVlodHRwczovL255cG9zdC5jb20vMjAyMi8wNy8yNy95YW5rZWVzLXZzLW1ldHMtc3Vid2F5LXNlcmllcy0yMDIyLWdhbWUtMi1saXZlLXVwZGF0ZXMvYW1wLw?oc=5" target="_blank">Subway Series live updates: Starling Marte's walk-off single gives Mets sweep over Yankees</a>&nbsp;&nbsp;<font color="#6f6f6f">New York Post </font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vZGFpbHlrbmlja3MuY29tLzIwMjIvMDcvMjcvZG9ub3Zhbi1taXRjaGVsbC1zdWJ3YXktc2VyaWVzLWVhZ2VyLWtuaWNrcy10cmFkZS_SAVlodHRwczovL2RhaWx5a25pY2tzLmNvbS8yMDIyLzA3LzI3L2Rvbm92YW4tbWl0Y2hlbGwtc3Vid2F5LXNlcmllcy1lYWdlci1rbmlja3MtdHJhZGUvYW1wLw?oc=5" target="_blank">Donovan Mitchell’s presence at Subway Series makes fans more eager for Knicks trade</a>&nbsp;&nbsp;<font color="#6f6f6f">Daily Knicks</font></li></ol> + + + https://news.google.com/articles/CAIiEE2Lq5guzBY4y1fiNlTOjTgqMwgEKioIACIQcEhJdydtpNytrR0x-Eds4SoUCAoiEHBISXcnbaTcra0dMfhHbOEw4o7iBg?oc=5 + Mavi Garcia hit by own team car on hectic Tour de France Femmes gravel stage - Cyclingnews + 2022-07-27T15:03:50.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibmh0dHBzOi8vd3d3LmN5Y2xpbmduZXdzLmNvbS9uZXdzL21hdmktZ2FyY2lhLWhpdC1ieS1vd24tdGVhbS1jYXItb24taGVjdGljLXRvdXItZGUtZnJhbmNlLWZlbW1lcy1ncmF2ZWwtc3RhZ2Uv0gEA?oc=5" target="_blank">Mavi Garcia hit by own team car on hectic Tour de France Femmes gravel stage</a>&nbsp;&nbsp;<font color="#6f6f6f">Cyclingnews</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvc3BvcnRzL2N5Y2xpbmcvdG91ci1kZS1mcmFuY2UtZmVtYWxlLWN5Y2xpc3RzLmh0bWzSAQA?oc=5" target="_blank">At Tour de France Femmes, It’s a Steep Climb to Equality</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9US16dmQ1T01qbzTSAQA?oc=5" target="_blank">Riders Left In The Dust On The Gravel | Tour De France Femmes avec Zwift 2022 Stage 4 Highlights</a>&nbsp;&nbsp;<font color="#6f6f6f">GCN Racing</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYGh0dHBzOi8vd3d3LnZlbG9uZXdzLmNvbS9nYWxsZXJ5L2Rpc3BhdGNoLWRlcy1mZW1tZXMtdGhlLWNyb3dkcy1oYXZlLWJlZW4tdGhlLWljaW5nLW9uLXRoZS1jYWtlL9IBAA?oc=5" target="_blank">Dispatch des Femmes: The crowds have been the icing on the cake</a>&nbsp;&nbsp;<font color="#6f6f6f">VeloNews</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXmh0dHBzOi8vY3ljbGluZ3RpcHMuY29tLzIwMjIvMDcvYS1uaWdodG1hcmUtZm9yLWdhcmNpYS1hcy1vdGhlci1nYy1mYXZvdXJpdGVzLXRhbWUtdGhlLWdyYXZlbC_SAQA?oc=5" target="_blank">A nightmare for García as other GC favourites tame the gravel</a>&nbsp;&nbsp;<font color="#6f6f6f">CyclingTips</font></li></ol> + + + https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lPZ3VfU0JSSGl2b3hmS3BONjl5Z0FQAQ?oc=5 + NASA Will Send More Helicopters to Mars - The New York Times + 2022-07-27T22:46:18.000000000Z + + <a href="https://news.google.com/__i/rss/rd/articles/CBMiSGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvc2NpZW5jZS9tYXJzLXNhbXBsZS1taXNzaW9uLW5hc2EuaHRtbNIBAA?oc=5" target="_blank">NASA Will Send More Helicopters to Mars</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lPZ3VfU0JSSGl2b3hmS3BONjl5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong> + + + https://news.google.com/articles/CBMibGh0dHBzOi8vd3d3LnRoZWRhaWx5YmVhc3QuY29tL2NoaW5lc2Utcm9ja2V0LXdpbGwtY3Jhc2gtaW50by1lYXJ0aC1zdW5kYXlwb3NzaWJseS1pbnRvLWEtcG9wdWxhdGVkLWNvbW11bml0edIBAA?oc=5 + Chinese Rocket Will Crash Into Earth Sunday, Possibly Into a Populated Community - The Daily Beast + 2022-07-27T20:38:22.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LnRoZWRhaWx5YmVhc3QuY29tL2NoaW5lc2Utcm9ja2V0LXdpbGwtY3Jhc2gtaW50by1lYXJ0aC1zdW5kYXlwb3NzaWJseS1pbnRvLWEtcG9wdWxhdGVkLWNvbW11bml0edIBAA?oc=5" target="_blank">Chinese Rocket Will Crash Into Earth Sunday, Possibly Into a Populated Community</a>&nbsp;&nbsp;<font color="#6f6f6f">The Daily Beast</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MlI1NzhwYW1USjTSAQA?oc=5" target="_blank">Gravitas: Out-of-control Chinese rocket to crash on earth</a>&nbsp;&nbsp;<font color="#6f6f6f">WION</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibmh0dHBzOi8vd3d3LnJldXRlcnMuY29tL2xpZmVzdHlsZS9zY2llbmNlL2NoaW5hLWNsb3NlbHktdHJhY2tpbmctcmVtbmFudHMtaXRzLW1vc3QtcG93ZXJmdWwtcm9ja2V0LTIwMjItMDctMjcv0gEA?oc=5" target="_blank">China closely tracking debris of its most powerful rocket</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vd3d3LnlhaG9vLmNvbS9uZXdzL2NoaW5hLXNwYWNlY3JhZnQtcmV0dXJucy1hbWlkLWJvb3N0ZXItMTA1MjI2MTMzLmh0bWzSAVhodHRwczovL25ld3MueWFob28uY29tL2FtcGh0bWwvbmV3cy9jaGluYS1zcGFjZWNyYWZ0LXJldHVybnMtYW1pZC1ib29zdGVyLTEwNTIyNjEzMy5odG1s?oc=5" target="_blank">China spacecraft returns amid booster rocket concerns</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo! Voices</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiUmh0dHBzOi8vZ2l6bW9kby5jb20vY2hpbmEtb3V0LW9mLWNvbnRyb2wtcm9ja2V0LXByZWRpY3RlZC1jcmFzaC1qdWx5LTMxLTE4NDkzMzcyOTnSAVZodHRwczovL2dpem1vZG8uY29tL2NoaW5hLW91dC1vZi1jb250cm9sLXJvY2tldC1wcmVkaWN0ZWQtY3Jhc2gtanVseS0zMS0xODQ5MzM3Mjk5L2FtcA?oc=5" target="_blank">China’s Out-of-Control Rocket Predicted to Crash on July 30 [Updating]</a>&nbsp;&nbsp;<font color="#6f6f6f">Gizmodo</font></li></ol> + + + https://news.google.com/articles/CBMiMmh0dHBzOi8vd3d3Lm5hdHVyZS5jb20vYXJ0aWNsZXMvZDQxNTg2LTAyMi0wMjA1Ni010gEA?oc=5 + Four revelations from the Webb telescope about distant galaxies - Nature.com + 2022-07-27T16:42:46.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiMmh0dHBzOi8vd3d3Lm5hdHVyZS5jb20vYXJ0aWNsZXMvZDQxNTg2LTAyMi0wMjA1Ni010gEA?oc=5" target="_blank">Four revelations from the Webb telescope about distant galaxies</a>&nbsp;&nbsp;<font color="#6f6f6f">Nature.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MUhYN0RwMHprbVnSAQA?oc=5" target="_blank">James Webb space telescope: Why NASA is being pressured to change its name | WION Originals</a>&nbsp;&nbsp;<font color="#6f6f6f">WION</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vd3d3LnNwYWNlLmNvbS9qYW1lcy13ZWJiLXNwYWNlLXRlbGVzY29wZS1maXJzdC1zdXBlcm1hc3NpdmUtYmxhY2staG9sZXPSAQA?oc=5" target="_blank">The James Webb Space Telescope is on the hunt for the universe's 1st-ever supermassive black holes</a>&nbsp;&nbsp;<font color="#6f6f6f">Space.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vd3d3LmJvc3Rvbmdsb2JlLmNvbS8yMDIyLzA3LzI2L29waW5pb24vamFtZXMtd2ViYi1zcGFjZS10ZWxlc2NvcGUtaXMtZ2l2aW5nLWh1bWFuaXR5LXdoYXQtd2UtbmVlZC1yaWdodC1ub3cv0gEA?oc=5" target="_blank">The James Webb Space Telescope is giving humanity what we need right now</a>&nbsp;&nbsp;<font color="#6f6f6f">The Boston Globe</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vd3d3LnRoZXJlcHVibGljLmNvbS8yMDIyLzA3LzI3L25hc2FzLXdlYmItaW1hZ2VzLXByb3ZpZGUtYXN0b25pc2htZW50L9IBAA?oc=5" target="_blank">NASA’s Webb images provide astonishment</a>&nbsp;&nbsp;<font color="#6f6f6f">The Republic</font></li></ol> + + + https://news.google.com/articles/CBMiS2h0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy93b3JsZC9tYXJzLXNhbXBsZS1yZXR1cm4tMjAzMy1zY24vaW5kZXguaHRtbNIBT2h0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvd29ybGQvbWFycy1zYW1wbGUtcmV0dXJuLTIwMzMtc2NuL2luZGV4Lmh0bWw?oc=5 + First mission to return samples from another planet set to land on Earth in 2033 - CNN + 2022-07-27T20:40:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiS2h0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy93b3JsZC9tYXJzLXNhbXBsZS1yZXR1cm4tMjAzMy1zY24vaW5kZXguaHRtbNIBT2h0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvd29ybGQvbWFycy1zYW1wbGUtcmV0dXJuLTIwMzMtc2NuL2luZGV4Lmh0bWw?oc=5" target="_blank">First mission to return samples from another planet set to land on Earth in 2033</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiY2h0dHBzOi8vd3d3LmpwbC5uYXNhLmdvdi9uZXdzL25hc2Etd2lsbC1pbnNwaXJlLXdvcmxkLXdoZW4taXQtcmV0dXJucy1tYXJzLXNhbXBsZXMtdG8tZWFydGgtaW4tMjAzM9IBAA?oc=5" target="_blank">NASA Will Inspire World When It Returns Mars Samples to Earth in 2033</a>&nbsp;&nbsp;<font color="#6f6f6f">NASA Jet Propulsion Laboratory</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXmh0dHBzOi8vbmV3cy5hYnMtY2JuLmNvbS9zcG90bGlnaHQvMDcvMjgvMjIvbmFzYS1kZXRhaWxzLXBsYW5zLXRvLWJyaW5nLWJhY2stbWFycy1yb2NrLXNhbXBsZXPSAWJodHRwczovL25ld3MuYWJzLWNibi5jb20vYW1wL3Nwb3RsaWdodC8wNy8yOC8yMi9uYXNhLWRldGFpbHMtcGxhbnMtdG8tYnJpbmctYmFjay1tYXJzLXJvY2stc2FtcGxlcw?oc=5" target="_blank">NASA details plans to bring back Mars rock samples</a>&nbsp;&nbsp;<font color="#6f6f6f">ABS-CBN News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiemh0dHBzOi8vd3d3LjluZXdzLmNvbS5hdS93b3JsZC9uYXNhLW1hcnMtbWlzc2lvbi1ob3ctc2FtcGxlcy13aWxsLWJlLWJyb3VnaHQtdG8tZWFydGgvNWRiOTliYWUtZjAwMS00YWIzLWI4YzgtZmVmMzAyOTZhNzVh0gFFaHR0cHM6Ly9hbXAuOW5ld3MuY29tLmF1L2FydGljbGUvNWRiOTliYWUtZjAwMS00YWIzLWI4YzgtZmVmMzAyOTZhNzVh?oc=5" target="_blank">NASA reveals when first ever Mars samples will return to Earth</a>&nbsp;&nbsp;<font color="#6f6f6f">9News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vbWFycy5uYXNhLmdvdi9yZXNvdXJjZXMvMjY4OTUvbWFycy1zYW1wbGUtcmV0dXJuLWNvbmNlcHQtaWxsdXN0cmF0aW9uL9IBAA?oc=5" target="_blank">Mars Sample Return Concept Illustration – NASA Mars Exploration</a>&nbsp;&nbsp;<font color="#6f6f6f">NASA Mars Exploration</font></li></ol> + + + https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2kyMV9uU0JSRjBUd1l5TC13cHVTZ0FQAQ?oc=5 + Supplemental Vitamin D and Incident Fractures in Midlife and Older Adults | NEJM - nejm.org + 2022-07-27T21:01:41.000000000Z + + <a href="https://news.google.com/__i/rss/rd/articles/CBMiM2h0dHBzOi8vd3d3Lm5lam0ub3JnL2RvaS9mdWxsLzEwLjEwNTYvTkVKTW9hMjIwMjEwNtIBAA?oc=5" target="_blank">Supplemental Vitamin D and Incident Fractures in Midlife and Older Adults | NEJM</a>&nbsp;&nbsp;<font color="#6f6f6f">nejm.org</font><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2kyMV9uU0JSRjBUd1l5TC13cHVTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong> + + + https://news.google.com/articles/CBMiTGh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9oZWFsdGgvY2RjLW1lbGlvaWRvc2lzLW1pc3Npc3NpcHBpL2luZGV4Lmh0bWzSAVBodHRwczovL2FtcC5jbm4uY29tL2Nubi8yMDIyLzA3LzI3L2hlYWx0aC9jZGMtbWVsaW9pZG9zaXMtbWlzc2lzc2lwcGkvaW5kZXguaHRtbA?oc=5 + Bacteria that causes rare, serious illness melioidosis is endemic in parts of Mississippi Gulf Coast, CDC says - CNN + 2022-07-27T23:04:00.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9oZWFsdGgvY2RjLW1lbGlvaWRvc2lzLW1pc3Npc3NpcHBpL2luZGV4Lmh0bWzSAVBodHRwczovL2FtcC5jbm4uY29tL2Nubi8yMDIyLzA3LzI3L2hlYWx0aC9jZGMtbWVsaW9pZG9zaXMtbWlzc2lzc2lwcGkvaW5kZXguaHRtbA?oc=5" target="_blank">Bacteria that causes rare, serious illness melioidosis is endemic in parts of Mississippi Gulf Coast, CDC says</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvaGVhbHRoL2RlYWRseS1iYWN0ZXJpYS11cy1zb2lsLXdhdGVyLmh0bWzSAQA?oc=5" target="_blank">Potentially Deadly Bacteria Detected in U.S. Soil for First Time</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQmh0dHBzOi8vbmV3cy55YWhvby5jb20vY2RjLWZpcnN0LXRpbWUtc2FtcGxlcy10YWtlbi0yMDMyMzI5MjMuaHRtbNIBSmh0dHBzOi8vbmV3cy55YWhvby5jb20vYW1waHRtbC9jZGMtZmlyc3QtdGltZS1zYW1wbGVzLXRha2VuLTIwMzIzMjkyMy5odG1s?oc=5" target="_blank">CDC, for first time from samples taken in U.S., discovers bacteria that causes rare serious disease</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vd3d3LmFvbC5jb20vbmV3cy9iYWN0ZXJpYS1jYXVzZXMtcmFyZS10cm9waWNhbC1kaXNlYXNlLTE5NDU1Mjg3Ny0yMDA0MzQ1NDQuaHRtbNIBWmh0dHBzOi8vd3d3LmFvbC5jb20vYW1waHRtbC9iYWN0ZXJpYS1jYXVzZXMtcmFyZS10cm9waWNhbC1kaXNlYXNlLTE5NDU1Mjg3Ny0yMDA0MzQ1NDQuaHRtbA?oc=5" target="_blank">Bacteria that causes rare tropical disease found in US soil</a>&nbsp;&nbsp;<font color="#6f6f6f">AOL</font></li></ol> + + + https://news.google.com/articles/CAIiEBbfxQb6QzszfljxV-KoTbcqFwgEKg8IACoHCAowjuuKAzCWrzwwt4QY?oc=5 + U.S. to Distribute 800,000 Doses of Monkeypox Vaccine - The New York Times + 2022-07-27T22:31:50.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRmh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvaGVhbHRoL21vbmtleXBveC12YWNjaW5lLWRvc2VzLmh0bWzSAQA?oc=5" target="_blank">U.S. to Distribute 800,000 Doses of Monkeypox Vaccine</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiR2h0dHBzOi8vd3d3LmZveG5ld3MuY29tL2hlYWx0aC9ueWMtYXNrcy13aG8tcmVuYW1lLW1vbmtleXBveC1kdWUtc3RpZ21h0gFLaHR0cHM6Ly93d3cuZm94bmV3cy5jb20vaGVhbHRoL255Yy1hc2tzLXdoby1yZW5hbWUtbW9ua2V5cG94LWR1ZS1zdGlnbWEuYW1w?oc=5" target="_blank">NYC asks WHO to rename monkeypox due to stigma</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9SXJJcmZkX0pvMjDSAQA?oc=5" target="_blank">Nearly 800000 more monkeypox vaccine doses to be available in U.S.</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYmh0dHBzOi8vd3d3LnRpbWVvdXQuY29tL25ld3lvcmsvbmV3cy9tb25rZXlwb3gtaW4tbmV3LXlvcmstY2l0eS1oZXJlcy13aGF0LXlvdS1uZWVkLXRvLWtub3ctMDcyNzIy0gEA?oc=5" target="_blank">Monkeypox in New York City: Here's what you need to know</a>&nbsp;&nbsp;<font color="#6f6f6f">Time Out</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiemh0dHBzOi8vd3d3LnJldXRlcnMuY29tL3dvcmxkL2FtZXJpY2FzL21vbmtleXBveC1jYXNlcy1hbWVyaWNhcy1yZWFjaC01MzAwLXVzLWNhbmFkYS1icmF6aWwtbW9zdC1hZmZlY3RlZC1wYWhvLTIwMjItMDctMjcv0gEA?oc=5" target="_blank">Monkeypox cases in the Americas reach 5300; US, Canada, Brazil most affected -PAHO</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li></ol> + + + https://news.google.com/articles/CBMiaWh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vbmV3cy8yMDIyLzcvMjcvYXMtbW9ua2V5cG94LXN1cmdlcy13aG8tdXJnZXMtcmVkdWNpbmctbnVtYmVyLW9mLXNleHVhbC1wYXJ0bmVyc9IBbWh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vYW1wL25ld3MvMjAyMi83LzI3L2FzLW1vbmtleXBveC1zdXJnZXMtd2hvLXVyZ2VzLXJlZHVjaW5nLW51bWJlci1vZi1zZXh1YWwtcGFydG5lcnM?oc=5 + As monkeypox surges, WHO urges reducing number of sexual partners - Al Jazeera English + 2022-07-27T19:18:54.000000000Z + + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiaWh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vbmV3cy8yMDIyLzcvMjcvYXMtbW9ua2V5cG94LXN1cmdlcy13aG8tdXJnZXMtcmVkdWNpbmctbnVtYmVyLW9mLXNleHVhbC1wYXJ0bmVyc9IBbWh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vYW1wL25ld3MvMjAyMi83LzI3L2FzLW1vbmtleXBveC1zdXJnZXMtd2hvLXVyZ2VzLXJlZHVjaW5nLW51bWJlci1vZi1zZXh1YWwtcGFydG5lcnM?oc=5" target="_blank">As monkeypox surges, WHO urges reducing number of sexual partners</a>&nbsp;&nbsp;<font color="#6f6f6f">Al Jazeera English</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTWh0dHBzOi8vd3d3LmJ1enpmZWVkbmV3cy5jb20vYXJ0aWNsZS9kYXZpZG1hY2svbWVuLXNleC1wYXJ0bmVycy1tb25rZXlwb3gtd2hv0gEA?oc=5" target="_blank">Men Who Have Sex With Men Should Reduce Their Partners For Now To Avoid Monkeypox, The WHO Has Advised</a>&nbsp;&nbsp;<font color="#6f6f6f">BuzzFeed News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVmh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9oZWFsdGgvbW9ua2V5cG94LXZhY2NpbmUtaGVhbHRoLXdlbi13ZWxsbmVzcy9pbmRleC5odG1s0gFaaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9oZWFsdGgvbW9ua2V5cG94LXZhY2NpbmUtaGVhbHRoLXdlbi13ZWxsbmVzcy9pbmRleC5odG1s?oc=5" target="_blank">Now should I worry about monkeypox? Our medical analyst explains</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidWh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvbW9ua2V5cG94LXdoby1yZWNvbW1lbmRzLWdheS1iaXNleHVhbC1tZW4tbGltaXQtc2V4dWFsLXBhcnRuZXJzLXRvLXJlZHVjZS1zcHJlYWQuaHRtbNIBeWh0dHBzOi8vd3d3LmNuYmMuY29tL2FtcC8yMDIyLzA3LzI3L21vbmtleXBveC13aG8tcmVjb21tZW5kcy1nYXktYmlzZXh1YWwtbWVuLWxpbWl0LXNleHVhbC1wYXJ0bmVycy10by1yZWR1Y2Utc3ByZWFkLmh0bWw?oc=5" target="_blank">WHO recommends gay and bisexual men limit sexual partners to reduce the spread of monkeypox</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiSWh0dHBzOi8vd3d3Lm1lbnNoZWFsdGguY29tL2hlYWx0aC9hNDA3MTc4NzkvbW9ua2V5cG94LW1pc2luZm9ybWF0aW9uLXN0ZC_SAQA?oc=5" target="_blank">Calling Monkeypox an STI Isn't Just Misleading. It's Dangerous.</a>&nbsp;&nbsp;<font color="#6f6f6f">Men's Health</font></li></ol> + + diff --git a/test-data/atom-feed-standard.xml b/test-data/atom-feed-standard.xml new file mode 100644 index 0000000..fa99e35 --- /dev/null +++ b/test-data/atom-feed-standard.xml @@ -0,0 +1,30 @@ + + + Example Feed + A subtitle. + + + urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6 + 2003-12-13T18:30:02Z + + Atom-Powered Robots Run Amok + + + + urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a + 2003-11-09T17:23:02Z + 2003-12-13T18:30:02Z + Some text. + +
+

This is the entry content.

+
+
+ + John Doe + johndoe@example.com + +
+
diff --git a/test-data/another-atom.xml b/test-data/atom-multilinks.xml old mode 100755 new mode 100644 similarity index 84% rename from test-data/another-atom.xml rename to test-data/atom-multilinks.xml index 367feae..4a55efc --- a/test-data/another-atom.xml +++ b/test-data/atom-multilinks.xml @@ -12,7 +12,9 @@ Red wool sweater - + + + Comfortable and soft, this sweater will keep you warm on those cold winter nights. diff --git a/test-data/atom-with-single-item.xml b/test-data/atom-with-single-item.xml deleted file mode 100644 index 9694d8f..0000000 --- a/test-data/atom-with-single-item.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - https://news.google.com/atom?hl=en-US&gl=US&ceid=US:en - NFE/5.0 - Top stories - Google News - Google News - 2021-11-20T10:43:17.000000000Z - - Google Inc. - news-webmaster@google.com - https://news.google.com - - - - 2021 Google Inc. - - https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pPLWRxY0JCRVlmT2xQTzh2NmJTZ0FQAQ?oc=5 - Kyle Rittenhouse Breaks Silence After Not Guilty Verdict - NBC Chicago - 2021-11-20T07:25:12.000000000Z - - Something new here - - diff --git a/test-data/atom.xml b/test-data/atom.xml deleted file mode 100755 index 12e03f3..0000000 --- a/test-data/atom.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - https://news.google.com/atom?hl=en-US&gl=US&ceid=US:en - NFE/5.0 - Top stories - Google News - Google News - 2021-11-20T10:43:17.000000000Z - - Google Inc. - news-webmaster@google.com - https://news.google.com - - - - 2021 Google Inc. - - https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pPLWRxY0JCRVlmT2xQTzh2NmJTZ0FQAQ?oc=5 - Kyle Rittenhouse Breaks Silence After Not Guilty Verdict - NBC Chicago - 2021-11-20T07:25:12.000000000Z - - Something new here - - - https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lnODhTekJCRzl1Qmp5M1VNak5pZ0FQAQ?oc=5 - Biden gets first physical as president, power transferred to VP Harris - ABC News - 2021-11-19T23:26:15.000000000Z - - Something new here - - diff --git a/test-data/json-feed-standard-realworld.json b/test-data/json-feed-standard-realworld.json new file mode 100644 index 0000000..b0ee108 --- /dev/null +++ b/test-data/json-feed-standard-realworld.json @@ -0,0 +1,233 @@ + +{ + "version": "https://jsonfeed.org/version/1", + "title": "Adactio: Journal", + "description": "The online journal of Jeremy Keith, an author and web developer living and working in Brighton, England.", + "icon": "https://adactio.com/images/photo-600.jpg", + "favicon": "https://adactio.com/favicon-96x96.png", + "home_page_url": "https://adactio.com/journal/", + "feed_url": "https://adactio.com/journal/feed.json", + "author": { + "name": "Jeremy Keith" + }, + "items": [ + { + "id": "19317", + "url": "https://adactio.com/journal/19317", + "title": "The line-up for dConstruct 2022 …revealed!", + "summary": "Eight fantastic people who are going to provoke, entertain, and stimulate you.", + "date_published": "2022-07-26 13:01:01", + "tags": [ + "dconstruct", + "conferences", + "events", + "brighton", + "clearleft", + "lineup", + "speakers", + "tickets", + "medium:id=64164f20e87" + ], + "content_html": "

Alright, I’ve kept you in suspense for long enough. It’s time to reveal the magnificent line-up for dConstruct 2022.

I’ll now put names to the teasing list of descriptions I previously provided

A technologist, product designer, and writer who defies categorisation. They’ve headed up a design studio, co-founded a start-up, and now consult on super-clever machine learning stuff. Their blog is brilliant.

This is Matt Webb. Matt previously spoke at dConstruct back in 2007, when he gave a talk called The Experience Stack

An award-winning author from South Africa whose work has recently been adapted for television. Some of their work is kind of sci-fi, some of it is kind of horror, some of it is kind of magical realism, and all of it is great.

This is Lauren Beukes. Lauren previously spoke at dConstruct in 2012, when she gave a talk called Imagined Futures.

An artist and designer who has created logos and illustrations for NASA, Apple, and Intel as well as custom typefaces for British Airways and Waitrose. A lover of letterforms, they are now one of the world’s highest-profile calligraphers posting their mesmerising work on Instagram.

This is Seb Lester.

A Canadian digital designer who has previously worked in the agency world, at Silicon Valley startups, and even venture capital. But now they’re doing truly meaningful work, designing for busy healthcare workers in low-income countries.

This is Daniel Burka. Daniel previously spoke at dConstruct back in 2008, when he gave a talk called Designing for Interaction.

A multi-instrumentalist musician, producer and robotic artist who composes for film, theatre and the concert stage. They play a mean theremin.

This is Sarah Angliss. Sarah previously spoke at dConstruct in 2013, when she gave a talk called Tech and the Uncanny.

An Australian designer and entrepreneur. They work in the cultural heritage sector and they’re an expert on digital archives. Their latest challenge is working out how to make an online photography archive last for 100 years.

This is George Oates. George previously spoke at dConstruct back in 2007, where she and Denise Wilton had a conversation called Human Traffic.

A tireless defender of web standards and co-author of the Inclusive Design Principles. They’re a member of the W3C Advisory Board and of the BIMA Inclusive Design Council. Expect some thoughtful takes on the intersection of accessibility and emerging technologies.

This is Léonie Watson.

A professor of neuroscience who is also a bestselling author. They conduct experiments on people’s brains and then talk about it afterwards. Their talks have been known to be mind-altering.

This is Anil Seth.

That’s quite a line-up, isn’t it?

Deducing the full line-up just from those descriptions wasn’t easy, but Hidde de Vries managed it. So Hidde gets a free ticket to dConstruct 2022 …or, at least, he would if it weren’t for the fact that he already has a ticket (because Hidde is smart; be like Hidde). So a friend of Hidde’s is getting a free ticket instead (because Hidde is generous; be like Hidde).

If you’ve been putting off getting a ticket for dConstruct 2022 until you knew what the line-up would be, well, put off no longer.

You’ll want to be at the Duke of York’s in Brighton on Friday, September 9th. With this line-up of eight supersmart speakers, you know it’s going to be a fantastic day!

" + } +, { + "id": "19315", + "url": "https://adactio.com/journal/19315", + "title": "Control", + "summary": "Trying to understand a different mindset to mine.", + "date_published": "2022-07-25 15:36:20", + "tags": [ + "control", + "trust", + "suspicion", + "browsers", + "html", + "interface", + "us", + "buttons", + "dropdowns", + "selects", + "datepickers", + "components", + "css", + "styling", + "javascript", + "aria", + "interaction", + "interactvity", + "mindset", + "frontend", + "development", + "medium:id=ee4a968f2f31" + ], + "content_html": "

In two of my recent talks—In And Out Of Style and Design Principles For The Web—I finish by looking at three different components:

  1. a button,
  2. a dropdown, and
  3. a datepicker.

In each case you could use native HTML elements:

  1. button,
  2. select, and
  3. input type=\"date\".

Or you could use divs with a whole bunch of JavaScript and ARIA.

In the case of a datepicker, I totally understand why you’d go for writing your own JavaScript and ARIA. The native HTML element is quite restricted, especially when it comes to styling.

In the case of a dropdown, it’s less clear-cut. Personally, I’d use a select element. While it’s currently impossible to style the open state of a select element, you can style the closed state with relative ease. That’s good enough for me.

Still, I can understand why that wouldn’t be good enough for some cases. If pixel-perfect consistency across platforms is a priority, then you’re going to have to break out the JavaScript and ARIA.

Personally, I think chasing pixel-perfect consistency across platforms isn’t even desirable, but I get it. I too would like to have more control over styling select elements. That’s one of the reasons why the work being done by the Open UI group is so important.

But there’s one more component: a button.

Again, you could use the native button element, or you could use a div or a span and add your own JavaScript and ARIA.

Now, in this case, I must admit that I just don’t get it. Why wouldn’t you just use the native button element? It has no styling issues and the browser gives you all the interactivity and accessibility out of the box.

I’ve been trying to understand the mindset of a developer who wouldn’t use a native button element. The easy answer would be that they’re just bad people, and dismiss them. But that would probably be lazy and inaccurate. Nobody sets out to make a website with poor performance or poor accessibility. And yet, by choosing not to use the native HTML element, that’s what’s likely to happen.

I think I might have finally figured out what might be going on in the mind of such a developer. I think the issue is one of control.

When I hear that there’s a native HTML element—like button or select—that comes with built-in behaviours around interaction and accessibility, I think “Great! That’s less work for me. I can just let the browser deal with it.” In other words, I relinquish control to the browser (though not entirely—I still want the styling to be under my control as much as possible).

But I now understand that someone else might hear that there’s a native HTML element—like button or select—that comes with built-in behaviours around interaction and accessibility, and think “Uh-oh! What if there unexpected side-effects of these built-in behaviours that might bite me on the ass?” In other words, they don’t trust the browsers enough to relinquish control.

I get it. I don’t agree. But I get it.

If your background is in computer science, then the ability to precisely predict how a programme will behave is a virtue. Any potential side-effects that aren’t within your control are undesirable. The only way to ensure that an interface will behave exactly as you want is to write it entirely from scratch, even if that means using more JavaScript and ARIA than is necessary.

But I don’t think it’s a great mindset for the web. The web is filled with uncertainties—browsers, devices, networks. You can’t possibly account for all of the possible variations. On the web, you have to relinquish some control.

Still, I’m glad that I now have a bit more insight into why someone would choose to attempt to retain control by using div, JavaScript and ARIA. It’s not what I would do, but I think I understand the motivation a bit better now.

" + } +, { + "id": "19302", + "url": "https://adactio.com/journal/19302", + "title": "Scale", + "summary": "Temperature and music.", + "date_published": "2022-07-21 17:41:14", + "tags": [ + "temperature", + "heat", + "cold", + "weather", + "music", + "instruments", + "tuning", + "interface", + "ui", + "medium:id=192eeb0219e4" + ], + "content_html": "

A few years back, Jessica got a ceiling fan for our living room. This might seem like a strange decision, considering we live in England. Most of the time, the problem in this country is that it’s too cold.

But then you get situations like this week, when the country experienced the hottest temperatures ever recorded. I was very, very grateful for that ceiling fan. It may not get used for most of the year, but on the occasions when it’s needed, it’s a godsend. And it’s going to get used more and more often, given the inexorable momentum of the climate emergency.

Even with the ceiling fan, it was still very hot in the living room. I keep my musical instruments in that room, and they all responded to the changing temperature. The strings on my mandolin, bouzouki, and guitar went looser in the heat. The tuning dropped by at least a semitone.

I tuned them back up, but then I had to be careful when the extreme heat ended and the temperature began to drop. The strings began to tighten accordingly. My instruments went up a semitone.

I was thinking about this connection between sound and temperature when I was tuning the instruments back down again.

The electronic tuner I use shows the current tone in relation to the desired note: G, D, A, E. If the string is currently producing a tone that’s lower than, say, A, the tuner displays the difference on its little screen as lines behind the ideal A position. If the string is producing a tone higher than A, the lines appear in front of the desired note.

What if we thought about temperature like this? Instead of weather apps showing the absolute temperature in degrees, what if they showed the relative distance from a predefined ideal? Then you could see at a glance whether it’s a little cooler than you’d like, or a little hotter than you’d like.

Perhaps an interface like that would let you see at a glance how out of the tune the current temperature is.

" + } +, { + "id": "19299", + "url": "https://adactio.com/journal/19299", + "title": "Subscribing to newsletters", + "summary": "But not like that.", + "date_published": "2022-07-20 15:30:10", + "tags": [ + "rss", + "feeds", + "reading", + "feedreaders", + "newsletters", + "email", + "writing", + "publishing", + "medium:id=9f22f6270a9a" + ], + "content_html": "

I like reading RSS feeds. I’ve written before about how my feed reader feels different to my email client:

When I open my RSS reader to catch up on the feeds I’m subscribed to, it doesn’t feel like opening my email client. It feels more like opening a book. And, yes, books are also things to be completed—a bookmark not only marks my current page, it also acts as a progress bar—but books are for pleasure. The pleasure might come from escapism, or stimulation, or the pursuit of knowledge. That’s a very different category to email, calendars, and Slack.

Giles put it far better when described what using RSS feeds feels like:

To me, using RSS feeds to keep track of stuff I’m interested in is a good use of my time. It doesn’t feel like a burden, it doesn’t feel like I’m being tracked or spied on, and it doesn’t feel like I’m just another number in the ads game.

To me, it feels good. It’s a way of reading the web that better respects my time, is more likely to appeal to my interests, and isn’t trying to constantly sell me things.

That’s why I feel somewhat conflicted about email newsletters. On the one hand, people are publishing some really interesting things in newsletters. On the hand, the delivery mechanism is email, which feels burdensome. Add tracking into the mix, and they can feel downright icky.

But never fear! My feed reader came to the rescue. Many newsletter providers also provide RSS feeds. NetNewsWire—my feed reader of choice—will try to find the RSS feed that corresponds to the newsletter. Hurrah!

I get to read newsletters without being tracked, which is nice for me. But I also think it would be nice to let the authors of those newsletters know that I’m reading. So here’s a list of some of the newsletters I’m currently subscribed to in my feed reader:

The Whippet by McKinley Valentine:

A newsletter for the terminally curious.

Sentiers by Patrick Tanguay:

A carefully curated selection of articles with thoughtful commentary on technology, society, culture, and potential futures.

The Fitzwilliam:

Policy, ethics and applied rationality with an Irish slant.

The Science Of Fiction:

How science shapes stories about the future and how stories about the future shape science.

Adjacent Possible by Steven Johnson:

Exploring where good ideas come from—and how to keep them from turning against us.

Faster, Please! by James Pethokoukis:

Discovering, creating, and inventing a better world through technological innovation, economic growth, and pro-progress culture.

undefended / undefeated by Sara Hendren:

Ideas at the heart of material culture—the everyday stuff in all our lives

Today in Tabs by Rusty Foster:

Your favorite newsletter’s favorite newsletter.

" + } +, { + "id": "19291", + "url": "https://adactio.com/journal/19291", + "title": "The line-up for dConstruct 2022", + "summary": "Shall we play a game? If you’re first to figure out the line-up, you get a free ticket.", + "date_published": "2022-07-19 09:45:34", + "tags": [ + "dconstruct", + "conferences", + "events", + "brighton", + "clearleft", + "lineup", + "speakers", + "tickets", + "medium:id=3b7c50a5bf8c" + ], + "content_html": "

The line-up for dConstruct 2022 is complete!

If you haven’t yet got your ticket, it’s not too late.

Now here’s the thing…

When I announced the event back in May, I said:

I’m currently putting the line-up together. I’m not revealing anything just yet, but trust me, you will want to be there.

I still haven’t revealed anything, and I’m kind of tempted to keep it that way. Imagine showing up at an event and not knowing who’s going to be speaking. Is this is the best idea or the worst idea?

I suspect I’m going to have to announce the line-up at some point, but today is not that day. I’m going to string it out a bit longer.

But I am going to describe the line-up. And I’m going to throw in a challenge. The first person to figure out the complete line-up gets a free ticket. Send a tweet to the @dConstruct Twitter account with your deductions.

Ready? Here’s who’s speaking at dConstruct 2022 on Friday, September 9th in The Duke Of Yorks in Brighton…

  1. A technologist, product designer, and writer who defies categorisation. They’ve headed up a design studio, co-founded a start-up, and now consult on super-clever machine learning stuff. Their blog is brilliant.
  2. An award-winning author from South Africa whose work has recently been adapted for television. Some of their work is kind of sci-fi, some of it is kind of horror, some of it is kind of magical realism, and all of it is great.
  3. An artist and designer who has created logos and illustrations for NASA, Apple, and Intel as well as custom typefaces for British Airways and Waitrose. A lover of letterforms, they are now one of the world’s highest-profile calligraphers posting their mesmerising work on Instagram.
  4. A Canadian digital designer who has previously worked in the agency world, at Silicon Valley startups, and even venture capital. But now they’re doing truly meaningful work, designing for busy healthcare workers in low-income countries.
  5. A multi-instrumentalist musician, producer and robotic artist who composes for film, theatre and the concert stage. They play a mean theremin.
  6. An Australian designer and entrepreneur. They work in the cultural heritage sector and they’re an expert on digital archives. Their latest challenge is working out how to make an online photography archive last for 100 years.
  7. A tireless defender of web standards and co-author of the Inclusive Design Principles. They’re a member of the W3C Advisory Board and of the BIMA Inclusive Design Council. Expect some thoughtful takes on the intersection of accessibility and emerging technologies.
  8. A professor of neuroscience who is also a bestselling author. They conduct experiments on people’s brains and then talk about it afterwards. Their talks have been known to be mind-altering.

Sounds pretty freaking great, right?

Some further clues…

Many of these people have spoken at dConstruct in the past. After all, this year’s one-off event is going to be a kind of “best of.” So you might want to have a nose around the dConstruct archive.

Also, I’ve mentioned some nationalities like Australian, Canadian, and South African, but my self-imposed carbon footprint policy for this event forbids me from flying anyone in. So that’s a clue too.

The game is afoot! Tweet your deductions to the @dConstruct Twitter account or, even better, write a blog post and tweet the link, mentioning @dConstruct. The first correct answer gets a free ticket.

For everyone else, you can still get a ticket.

" + } +, { + "id": "19230", + "url": "https://adactio.com/journal/19230", + "title": "Negative", + "summary": "Have negative result, will travel.", + "date_published": "2022-06-30 13:21:45", + "tags": [ + "covid-19", + "coronavirus", + "pandemic", + "life", + "vaccines", + "travel", + "health", + "events", + "uxlondon", + "music", + "willieclancy", + "ireland", + "irish", + "traditional", + "music", + "medium:id=67fde38247c3" + ], + "content_html": "

I no longer have Covid. I am released from isolation.

Alas, my negative diagnosis came too late for me to make it to UX London. But that’s okay—by the third and final day of the event, everything was running smooth like buttah! Had I shown up, I would’ve just got in the way. The Clearleft crew ran the event like a well-oiled machine.

I am in the coronaclear just in time to go away for a week. My original thinking was this would be my post-UX-London break to rest up for a while, but it turns out I’ve been getting plenty of rest during UX London.

I’m heading to the west coast of Ireland for The Willie Clancy Summer School, a trad music pilgrimage.

Jessica and I last went to Willie Week in 2019. We had a great time and I distinctly remember thinking “I’m definitely coming back next year!”

Well, a global pandemic put paid to that. The event ran online for the past two years. But now that it’s back for real, I wouldn’t miss it for the world.

My mandolin and I are bound for Miltown Malbay!

" + } +, { + "id": "19229", + "url": "https://adactio.com/journal/19229", + "title": "Two books", + "summary": "A Ghost In The Throat and No One Is Talking About This.", + "date_published": "2022-06-29 15:43:02", + "tags": [ + "books", + "reading", + "fiction", + "writing", + "novels", + "medium:id=1b49d3ef90ca" + ], + "content_html": "

I’ve mentioned before that I like to read a mixture of fiction of non-fiction. In fact, I try to alternate between the two. If I’ve just read some non-fiction, then I’ll follow it with a novel and I’ve just read some fiction, then I’ll follow it with some non-fiction.

But those categorisations can be slippery. I recently read two books that were ostensibly fiction but were strongly autobiographical and didn’t have the usual narrative structure of a novel.

Just to clarify, I’m not complaining! Quite the opposite. I enjoy the discomfort of not being able to pigeonhole a piece of writing so easily.

Also, both books were excellent.

The first one was A Ghost In The Throat by Doireann Ní Ghríofa. It’s sort of about the narrator’s obsessive quest to translate the Caoineadh Airt Uí Laoghaire. But it’s also about the translator’s life, which mirrors the author’s. And it’s about all life—life in its bodily, milky, bloody, crungey reality. The writing is astonishing, creating an earthy musky atmosphere. It feels vibrant and new but somehow ancient and eternal at the same time.

By contrast, No One Is Talking About This by Patricia Lockwood is rooted in technology. Reading the book feels like scrolling through Twitter, complete with nervous anxiety. Again, the narrator’s life mirrors that of the author, but this time the style has more of the arch detachment of the modern networked world.

It took me a little while at first, but then I settled into the book’s cadence and vibe. Then, once I felt like I had a handle on the kind of book I was reading, it began to subtly change. I won’t reveal how, because I want you to experience that change for yourself. It’s like a slow-building sucker punch.

When I started reading No One Is Talking About This, I thought it might end up being the kind of book where I would admire the writing, but it didn’t seem like a work that invited emotional connection.

I couldn’t have been more wrong. I can’t remember the last time a book had such an emotional impact on me. Maybe that’s because it so deliberately lowered my defences, but damn, when I finished reading the book, I was in pieces.

I’m still not quite sure how to classify A Ghost In The Throat or No One Is Talking About This but I don’t care. They’re both just great books.

" + } +, { + "id": "19225", + "url": "https://adactio.com/journal/19225", + "title": "UX FOMO", + "summary": "Missing out on the event I curated.", + "date_published": "2022-06-28 15:01:39", + "tags": [ + "uxlondon", + "conferences", + "events", + "clearleft", + "curation", + "talks", + "presentations", + "workshops", + "fomo", + "covid", + "coronavirus", + "medium:id=6979dd639391" + ], + "content_html": "

Today is the first day of UX London 2022 …and I’m not there. Stoopid Covid.

I’m still testing positive although I’m almost certainly near the end of my infection. But I don’t want to take any chances. Much as I hate to miss out on UX London, I would hate passing this on even more. So my isolation continues.

Chris jumped in at the last minute to do the hosting duties—thanks, Chris!

From the buzz I’m seeing on Twitter, it sounds like everything is going just great without me, which is great to see. Still, I’m experiencing plenty of FOMO—even more than the usual levels of FOMO I’d have when there’s a great conference happening that I’m not at.

To be honest, nearly all of my work on UX London was completed before the event. My number one task was putting the line-up together, and I have to say, I think I nailed it.

If I were there to host the event, it would mostly be for selfish reasons. I’d get a real kick out of introducing each one of the superb speakers. I’d probably get very tedious, repeatedly saying “Oh, you’re going to love this next one!” followed by “Wasn’t that great‽”

But UX London isn’t about me. It’s about the inspiring talks and practical workshops.

I wish I were there to experience it in person but I can still bask in the glow of a job well done, hearing how much people are enjoying the event.

" + } +, { + "id": "19222", + "url": "https://adactio.com/journal/19222", + "title": "On reading", + "summary": "Words on screens. Words on paper.", + "date_published": "2022-06-27 16:04:58", + "tags": [ + "reading", + "ontyranny", + "books", + "screens", + "politics", + "technology", + "words", + "paper", + "medium:id=7989c5fbb000" + ], + "content_html": "

On Tyranny by Timothy Snyder is a very short book. Most of the time, this is a feature, not a bug.

There are plenty of non-fiction books I’ve read that definitely could’ve been much, much shorter. Books that have a good sensible idea, but one that could’ve been written on the back of a napkin instead of being expanded into an arbitrarily long form.

In the world of fiction, there’s the short story. I guess the equivelent in the non-fiction world is the essay. But On Tyranny isn’t an essay. It’s got chapters. They’re just really, really short.

Sometimes that brevity means that nuance goes out the window. What might’ve been a subtle argument that required paragraphs of pros and cons in another book gets reduced to a single sentence here. Mostly that’s okay.

The premise of the book is that Trump’s America is comparable to Europe in the 1930s:

We are no wiser than the Europeans who saw democracy yield to fascism, Nazism, or communism. Our one advantage is that we might learn from their experience.

But in making the comparison, Synder goes all in. There’s very little accounting for the differences between the world of the early 20th century and the world of the early 21st century.

This becomes really apparent when it comes to technology. One piece of advice offered is:

Make an effort to separate yourself from the internet. Read books.

Wait. He’s not actually saying that words on screens are in some way inherently worse than words on paper, is he? Surely that’s just the nuance getting lost in the brevity, right?

Alas, no:

Staring at screens is perhaps unavoidable but the two-dimensional world makes little sense unless we can draw upon a mental armory that we have developed somewhere else. … So get screens out of your room and surround yourself with books.

I mean, I’m all for reading books. But books are about what’s in them, not what they’re made of. To value words on a page more than the same words on a screen is like judging a book by its cover; its judging a book by its atoms.

For a book that’s about defending liberty and progress, On Tyranny is puzzingly conservative at times.

" + } +, { + "id": "19216", + "url": "https://adactio.com/journal/19216", + "title": "Talking about style", + "summary": "The transcript of a talk.", + "date_published": "2022-06-24 12:17:39", + "tags": [ + "talk", + "presentation", + "conferences", + "speaking", + "transcript", + "transcription", + "cssday", + "aneventapart", + "aea", + "frontend", + "development", + "styling", + "style", + "audio", + "video", + "medium:id=84c71404f6d9" + ], + "content_html": "

I’ve published a transcription of the talk I gave at CSS Day:

In And Out Of Style.

The title is intended to have double meaning. The obvious reference is that CSS is about styling web pages. But the talk also covers some long-term trends looking at ideas that have appear, disappear, and reappear over time. Hence, style as in trends and fashion.

There are some hyperlinks in the transcript but I also published a list of links if you’re interested in diving deeper into some of the topics mentioned in the talk.

I also published the slides but, as usual, they don’t make much sense out of context. They’re on Noti.st too.

I made an audio recording for your huffduffing pleasure.

There are two videos of this talk. On Vimeo, there’s the version I pre-recorded for An Event Apart online. On YouTube, there’s the recording from CSS Day.

It’s kind of interesting to compare the two (well, interesting to me, anyway). The pre-recorded version feels like a documentary. The live version has more a different vibe and it obviously has more audience interaction. I think my style of delivery suits a live audience best.

I invite you to read, watch, or listen to In And Out Of Style, whichever you prefer.

" + } + ] +} diff --git a/test-data/json-feed-standard.json b/test-data/json-feed-standard.json new file mode 100644 index 0000000..fba23b7 --- /dev/null +++ b/test-data/json-feed-standard.json @@ -0,0 +1,23 @@ +{ + "version": "https://jsonfeed.org/version/1", + "title": "JSON Feed", + "icon": "https://micro.blog/jsonfeed/avatar.jpg", + "home_page_url": "https://www.jsonfeed.org/", + "feed_url": "https://www.jsonfeed.org/feed.json", + "items": [ + { + "id": "http://jsonfeed.micro.blog/2020/08/07/json-feed-version.html", + "title": "JSON Feed version 1.1", + "content_html": "

We’ve updated the spec to version 1.1. It’s a minor update to JSON Feed, clarifying a few things in the spec and adding a couple new fields such as authors and language.

\n\n

For version 1.1, we’re starting to move to the more specific MIME type application/feed+json. Clients that parse HTML to discover feeds should prefer that MIME type, while still falling back to accepting application/json too.

\n\n

The code page has also been updated with several new code libraries and apps that support JSON Feed.

\n", + "date_published": "2020-08-07T11:44:36-05:00", + "url": "https://www.jsonfeed.org/2020/08/07/json-feed-version.html" + }, + { + "id": "http://jsonfeed.micro.blog/2017/05/17/announcing-json-feed.html", + "title": "Announcing JSON Feed", + "content_html": "\n\n

We — Manton Reece and Brent Simmons — have noticed that JSON has become the developers’ choice for APIs, and that developers will often go out of their way to avoid XML. JSON is simpler to read and write, and it’s less prone to bugs.

\n\n

So we developed JSON Feed, a format similar to RSS and Atom but in JSON. It reflects the lessons learned from our years of work reading and publishing feeds.

\n\n

See the spec. It’s at version 1, which may be the only version ever needed. If future versions are needed, version 1 feeds will still be valid feeds.

\n\n

Notes

\n\n

We have a WordPress plugin and, coming soon, a JSON Feed Parser for Swift. As more code is written, by us and others, we’ll update the code page.

\n\n

See Mapping RSS and Atom to JSON Feed for more on the similarities between the formats.

\n\n

This website — the Markdown files and supporting resources — is up on GitHub, and you’re welcome to comment there.

\n\n

This website is also a blog, and you can subscribe to the RSS feed or the JSON feed (if your reader supports it).

\n\n

We worked with a number of people on this over the course of several months. We list them, and thank them, at the bottom of the spec. But — most importantly — Craig Hockenberry spent a little time making it look pretty. :)

\n", + "date_published": "2017-05-17T10:02:12-05:00", + "url": "https://www.jsonfeed.org/2017/05/17/announcing-json-feed.html" + } + ] +} diff --git a/test-data/rss-feed-standard-realworld.xml b/test-data/rss-feed-standard-realworld.xml new file mode 100644 index 0000000..2052324 --- /dev/null +++ b/test-data/rss-feed-standard-realworld.xml @@ -0,0 +1,318 @@ + + + + NFE/5.0 + Top stories - Google News + https://news.google.com/?hl=en-US&gl=US&ceid=US:en + en-US + news-webmaster@google.com + 2022 Google Inc. + Thu, 28 Jul 2022 03:39:57 GMT + Google News + + In a major boost to Democrats, Manchin and Schumer announce deal for energy and health care bill - CNN + https://news.google.com/__i/rss/rd/articles/CBMiWWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9zY2h1bWVyLW1hbmNoaW4tZGVhbC1idWlsZC1iYWNrLWJldHRlci9pbmRleC5odG1s0gFdaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9zY2h1bWVyLW1hbmNoaW4tZGVhbC1idWlsZC1iYWNrLWJldHRlci9pbmRleC5odG1s?oc=5 + 1516137394 + Thu, 28 Jul 2022 02:43:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9zY2h1bWVyLW1hbmNoaW4tZGVhbC1idWlsZC1iYWNrLWJldHRlci9pbmRleC5odG1s0gFdaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9zY2h1bWVyLW1hbmNoaW4tZGVhbC1idWlsZC1iYWNrLWJldHRlci9pbmRleC5odG1s?oc=5" target="_blank">In a major boost to Democrats, Manchin and Schumer announce deal for energy and health care bill</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3BvbGl0aWNzL21hbmNoaW4tc2NodW1lci1hZ3JlZS1yZWNvbmNpbGlhdGlvbi1kZWFsLWFmdGVyLW1vcmUtdGhhbi15ZWFyLXRhbGtz0gEA?oc=5" target="_blank">Manchin, Schumer agree to vastly pared back version of Build Back Better</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9bGxYQzJhNVcwR2fSAQA?oc=5" target="_blank">Senate Democrats reach deal on Inflation Reduction Act</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvdXMvcG9saXRpY3MvbWFuY2hpbi1jbGltYXRlLXRheC1iaWxsLmh0bWzSAQA?oc=5" target="_blank">Manchin, in Reversal, Agrees to Quick Action on Climate and Tax Plan</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWmh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3BvbGl0aWNzL2xhd21ha2Vycy1yZWFjdC1tYW5jaGluLXNjaHVtZXItYWdyZWUtcmVjb25jaWxpYXRpb24tZGVhbNIBAA?oc=5" target="_blank">Lawmakers react after Manchin, Schumer agree to reconciliation deal: 'Build Back Broke'</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2l5MV9uU0JSRXJHak9UYVpSMTJpZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + CNN + + + CNN Exclusive: Biden administration offers convicted Russian arms dealer in exchange for Griner, Whelan - CNN + https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9ncmluZXItd2hlbGFuLWJpZGVuLW9mZmVyLXZpa3Rvci1ib3V0LWV4Y2hhbmdlLXJ1c3NpYS1hcm1zLWRlYWxlci9pbmRleC5odG1s0gF4aHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9ncmluZXItd2hlbGFuLWJpZGVuLW9mZmVyLXZpa3Rvci1ib3V0LWV4Y2hhbmdlLXJ1c3NpYS1hcm1zLWRlYWxlci9pbmRleC5odG1s?oc=5 + 1514704380 + Thu, 28 Jul 2022 03:02:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9wb2xpdGljcy9ncmluZXItd2hlbGFuLWJpZGVuLW9mZmVyLXZpa3Rvci1ib3V0LWV4Y2hhbmdlLXJ1c3NpYS1hcm1zLWRlYWxlci9pbmRleC5odG1s0gF4aHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9wb2xpdGljcy9ncmluZXItd2hlbGFuLWJpZGVuLW9mZmVyLXZpa3Rvci1ib3V0LWV4Y2hhbmdlLXJ1c3NpYS1hcm1zLWRlYWxlci9pbmRleC5odG1s?oc=5" target="_blank">CNN Exclusive: Biden administration offers convicted Russian arms dealer in exchange for Griner, Whelan</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UE8zaXM2OFJWTWvSAQA?oc=5" target="_blank">U.S. offers deal to free Brittney Griner and Paul Whelan from Russia</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMicGh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3Nwb3J0cy91cy1vZmZlcnMtc3Vic3RhbnRpYWwtcHJvcG9zYWwtYnJpbmctYnJpdHRuZXktZ3JpbmVyLXBhdWwtd2hlbGFuLWhvbWUtZnJvbS1ydXNzaWHSAQA?oc=5" target="_blank">US offers 'substantial proposal' to bring Brittney Griner, Paul Whelan home from Russia</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WmptcmxGeVdiVm_SAQA?oc=5" target="_blank">US offers 'merchant of death' in exchange for Griner, Whelan</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQGh0dHBzOi8vd3d3Lm55dGltZXMuY29tL2xpdmUvMjAyMi8wNy8yNy93b3JsZC9ydXNzaWEtd2FyLXVrcmFpbmXSAQA?oc=5" target="_blank">Russia-Ukraine News: Live Updates</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2o4bTZMU0JSRmhZaThHSkV3MHVTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + CNN + + + Covid Mask Mandate: Beverly Hills, 3 Other Local Cities Will Not Comply With L.A. Order - Deadline + https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vZGVhZGxpbmUuY29tLzIwMjIvMDcvY292aWQtbWFzay1tYW5kYXRlLWJldmVybHktaGlsbHMtbG9zLWFuZ2VsZXMtMTIzNTA3OTU0OC_SAQA?oc=5 + 1515279980 + Thu, 28 Jul 2022 01:13:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vZGVhZGxpbmUuY29tLzIwMjIvMDcvY292aWQtbWFzay1tYW5kYXRlLWJldmVybHktaGlsbHMtbG9zLWFuZ2VsZXMtMTIzNTA3OTU0OC_SAQA?oc=5" target="_blank">Covid Mask Mandate: Beverly Hills, 3 Other Local Cities Will Not Comply With L.A. Order</a>&nbsp;&nbsp;<font color="#6f6f6f">Deadline</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9SFJrcHFIQlFELWvSAQA?oc=5" target="_blank">Indoor mask mandate in LA County could be paused</a>&nbsp;&nbsp;<font color="#6f6f6f">FOX 11 Los Angeles</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9YTVhYmhnY0hlSzDSAQA?oc=5" target="_blank">Pasadena, Long Beach health officials say no to indoor mask mandate proposal</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS Los Angeles</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiP2h0dHBzOi8vd3d3LnNhY2JlZS5jb20vb3Bpbmlvbi9lZGl0b3JpYWxzL2FydGljbGUyNjM4NDAzNDcuaHRtbNIBAA?oc=5" target="_blank">Mask mandates remain the best way to defeat spread of virus</a>&nbsp;&nbsp;<font color="#6f6f6f">Sacramento Bee</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pzck1YU0JSRllfdXR3UDJYaHBTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Deadline + + + Biden's call with Xi Jinping will focus on areas of U.S.-China cooperation, not just tension - CNBC + https://news.google.com/__i/rss/rd/articles/CBMifGh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvYmlkZW5zLWNhbGwtd2l0aC14aS1qaW5waW5nLXdpbGwtaW5jbHVkZS1hcmVhcy1vZi11cy1jaGluYS1jb29wZXJhdGlvbi1ub3QtanVzdC10ZW5zaW9uLmh0bWzSAQA?oc=5 + 1506372879 + Wed, 27 Jul 2022 22:19:58 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMifGh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvYmlkZW5zLWNhbGwtd2l0aC14aS1qaW5waW5nLXdpbGwtaW5jbHVkZS1hcmVhcy1vZi11cy1jaGluYS1jb29wZXJhdGlvbi1ub3QtanVzdC10ZW5zaW9uLmh0bWzSAQA?oc=5" target="_blank">Biden's call with Xi Jinping will focus on areas of U.S.-China cooperation, not just tension</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3dvcmxkL2NoaW5hLXdhcm5zLWZpcm0tYWJzb2x1dGUtcmVzcG9uc2Utc3BlYWtlci1wZWxvc2ktdmlzaXRzLXRhaXdhbtIBAA?oc=5" target="_blank">China warns of 'firm' and 'absolute' response if Speaker Pelosi visits Taiwan</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS9vcGluaW9ucy8yMDIyLzA3LzI3L3BlbG9zaS12aXNpdC10YWl3YW4tY2hpbmEtaW5mbHVlbmNlL9IBAA?oc=5" target="_blank">Opinion | Pelosi's visit to Taiwan shouldn't be dissuaded by China</a>&nbsp;&nbsp;<font color="#6f6f6f">The Washington Post</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMicmh0dHBzOi8vd3d3LmJsb29tYmVyZy5jb20vb3Bpbmlvbi9hcnRpY2xlcy8yMDIyLTA3LTI2L2JpZGVuLXMtdGFpd2FuLXN0cmF0ZWd5LWlzLWZsYXdlZC13aGV0aGVyLXBlbG9zaS1nb2VzLW9yLW5vdNIBAA?oc=5" target="_blank">Biden's Taiwan Strategy Is Flawed Whether Pelosi Goes or Not</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lQMnFYT0JSRkFHVlVvdGxrc195Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + CNBC + + + Highland Park shooting suspect has been indicted on 117 counts by a grand jury - CNN + https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy91cy9oaWdobGFuZC1wYXJrLXN1c3BlY3RlZC1zaG9vdGVyLWNoYXJnZXMvaW5kZXguaHRtbNIBWGh0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvdXMvaGlnaGxhbmQtcGFyay1zdXNwZWN0ZWQtc2hvb3Rlci1jaGFyZ2VzL2luZGV4Lmh0bWw?oc=5 + 1516081343 + Thu, 28 Jul 2022 02:07:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy91cy9oaWdobGFuZC1wYXJrLXN1c3BlY3RlZC1zaG9vdGVyLWNoYXJnZXMvaW5kZXguaHRtbNIBWGh0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvdXMvaGlnaGxhbmQtcGFyay1zdXNwZWN0ZWQtc2hvb3Rlci1jaGFyZ2VzL2luZGV4Lmh0bWw?oc=5" target="_blank">Highland Park shooting suspect has been indicted on 117 counts by a grand jury</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9Rnd3YVUyX0VxbzDSAQA?oc=5" target="_blank">Highland Park gunman indicted on 117 felony charges</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS Chicago</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMijQFodHRwczovL3d3dy5sYWtlbWNoZW5yeXNjYW5uZXIuY29tLzIwMjIvMDcvMjcvZ3JhbmQtanVyeS1pbmRpY3RzLWhpZ2hsYW5kLXBhcmstcGFyYWRlLXNob290aW5nLW9uLTExNy1jaGFyZ2VzLWZvci1raWxsaW5nLTctaW5qdXJpbmctb3Zlci00NS_SAQA?oc=5" target="_blank">Grand jury indicts Highland Park parade shooting on 117 charges for killing 7, injuring over 45</a>&nbsp;&nbsp;<font color="#6f6f6f">Lake and McHenry County Scanner</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZmh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3VzL2hpZ2hsYW5kLXBhcmstZm91cnRoLWp1bHktc2hvb3Rpbmctc3VzcGVjdC1yb2JlcnQtY3JpbW8taW5kaWN0ZWQtMTE3LWNvdW50c9IBAA?oc=5" target="_blank">Highland Park Fourth of July shooting suspect Robert Crimo indicted on 117 counts</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lfb2ZiU0JSSF95ZVE0MTdjNGxpZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + CNN + + + As Mega Millions hits $1 billion, past lottery winners show the money can bring heartache and pain - The Washington Post + https://news.google.com/__i/rss/rd/articles/CBMiYWh0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS9uYXRpb24vMjAyMi8wNy8yNy9tZWdhLW1pbGxpb25zLWJpbGxpb24tamFja3BvdC13aW5uZXJzLWhhcHBpbmVzcy_SAQA?oc=5 + 1493925593 + Wed, 27 Jul 2022 23:05:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYWh0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS9uYXRpb24vMjAyMi8wNy8yNy9tZWdhLW1pbGxpb25zLWJpbGxpb24tamFja3BvdC13aW5uZXJzLWhhcHBpbmVzcy_SAQA?oc=5" target="_blank">As Mega Millions hits $1 billion, past lottery winners show the money can bring heartache and pain</a>&nbsp;&nbsp;<font color="#6f6f6f">The Washington Post</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibWh0dHBzOi8vd3d3LmZveGJ1c2luZXNzLmNvbS9lY29ub215L21lZ2EtbWlsbGlvbnMtamFja3BvdC1zd2VsbHMtb3Zlci0xYi1hZnRlci1uby13aW5uZXItbWFzc2l2ZS04MzBtLWRyYXdpbmfSAQA?oc=5" target="_blank">Mega Millions jackpot swells to over $1B after no winner in massive $830M drawing</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox Business</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9d1FFZXlvQVlCRkXSAQA?oc=5" target="_blank">No Mega Millions jackpot, but 4 $1 million winners between NY, NJ</a>&nbsp;&nbsp;<font color="#6f6f6f">PIX11 News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMieGh0dHBzOi8vd3d3LmNoaWNhZ290cmlidW5lLmNvbS9uYXRpb24td29ybGQvY3QtYXVkLW53LW1lZ2EtbWlsbGlvbnMtcHJpemUtMjAyMjA3MjctbzRwb20yNTMzbmZ0ZGhkbHhqYTJ3N2luYXUtc3RvcnkuaHRtbNIBAA?oc=5" target="_blank">Confused by the huge Mega Millions prize? Here are some answers.</a>&nbsp;&nbsp;<font color="#6f6f6f">Chicago Tribune</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vZm94OC5jb20vbmV3cy8xYi1tZWdhLW1pbGxpb25zLWphY2twb3Qtc3VycHJpc2luZy10aGluZ3MteW91LWNvdWxkLWJ1eS_SAQA?oc=5" target="_blank">$1B Mega Millions jackpot: Surprising things you could buy</a>&nbsp;&nbsp;<font color="#6f6f6f">WJW FOX 8 News Cleveland</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2paX2EzSUJSRk96VUdqN1ZOQUZTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + The Washington Post + + + 2 ex-Minneapolis officers sentenced to federal prison; 3.5 years for Thao, 3 years for Kueng - KSTP + https://news.google.com/__i/rss/rd/articles/CBMicmh0dHBzOi8va3N0cC5jb20va3N0cC1uZXdzL3RvcC1uZXdzLzItZXgtbWlubmVhcG9saXMtb2ZmaWNlcnMtc2VudGVuY2VkLWZlZGVyYWwtcHJpc29uLXRvdS10aGFvLWotYWxleGFuZGVyLWt1ZW5nL9IBAA?oc=5 + 1506097043 + Wed, 27 Jul 2022 19:58:57 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMicmh0dHBzOi8va3N0cC5jb20va3N0cC1uZXdzL3RvcC1uZXdzLzItZXgtbWlubmVhcG9saXMtb2ZmaWNlcnMtc2VudGVuY2VkLWZlZGVyYWwtcHJpc29uLXRvdS10aGFvLWotYWxleGFuZGVyLWt1ZW5nL9IBAA?oc=5" target="_blank">2 ex-Minneapolis officers sentenced to federal prison; 3.5 years for Thao, 3 years for Kueng</a>&nbsp;&nbsp;<font color="#6f6f6f">KSTP</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9dmh3N1p0d3hEc3fSAQA?oc=5" target="_blank">Two Former Minneapolis Officers Sentenced To Prison For Violating George Floyd's Rights</a>&nbsp;&nbsp;<font color="#6f6f6f">NBC News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiMWh0dHBzOi8vd3d3LmJiYy5jb20vbmV3cy93b3JsZC11cy1jYW5hZGEtNjIzMjExOTHSATVodHRwczovL3d3dy5iYmMuY29tL25ld3Mvd29ybGQtdXMtY2FuYWRhLTYyMzIxMTkxLmFtcA?oc=5" target="_blank">George Floyd death: Last two ex-officers sentenced to prison</a>&nbsp;&nbsp;<font color="#6f6f6f">BBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMinAFodHRwczovL3d3dy5rYXJlMTEuY29tL2FydGljbGUvbmV3cy9sb2NhbC9nZW9yZ2UtZmxveWQvdGhhby1rdWVuZy1mZWRlcmFsLXNlbnRlbmNpbmctbWlubmVhcG9saXMtcG9saWNlLWdlb3JnZS1mbG95ZC84OS1iMDNkZDI4Ny1jMTA0LTQzOTItYjk1Yi01ZmQyODViNTFkOTHSAaABaHR0cHM6Ly93d3cua2FyZTExLmNvbS9hbXAvYXJ0aWNsZS9uZXdzL2xvY2FsL2dlb3JnZS1mbG95ZC90aGFvLWt1ZW5nLWZlZGVyYWwtc2VudGVuY2luZy1taW5uZWFwb2xpcy1wb2xpY2UtZ2VvcmdlLWZsb3lkLzg5LWIwM2RkMjg3LWMxMDQtNDM5Mi1iOTViLTVmZDI4NWI1MWQ5MQ?oc=5" target="_blank">Ex-officers Kueng, Thao sentenced to federal prison for violating George Floyd's civil rights</a>&nbsp;&nbsp;<font color="#6f6f6f">KARE11.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WlVYX1B4cFNidzTSAQA?oc=5" target="_blank">Legal analyst discusses sentencing of ex-MPD officers Kueng, Thao</a>&nbsp;&nbsp;<font color="#6f6f6f">KARE 11</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lUNzVUT0JSSERjNkRSMGxOMkdTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + KSTP + + + Fed unleashes another big rate hike in bid to curb inflation - The Associated Press + https://news.google.com/__i/rss/rd/articles/CBMia2h0dHBzOi8vYXBuZXdzLmNvbS9hcnRpY2xlL2ZlZGVyYWwtcmVzZXJ2ZS1pbnRlcmVzdC1yYXRlLWhpa2UtbGl2ZS11cGRhdGVzLTZkYWIzOGI4MjM1YmM2MmJkZjY5YjQ3MTBjNmI4NGY10gEA?oc=5 + 1508833377 + Thu, 28 Jul 2022 02:49:58 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMia2h0dHBzOi8vYXBuZXdzLmNvbS9hcnRpY2xlL2ZlZGVyYWwtcmVzZXJ2ZS1pbnRlcmVzdC1yYXRlLWhpa2UtbGl2ZS11cGRhdGVzLTZkYWIzOGI4MjM1YmM2MmJkZjY5YjQ3MTBjNmI4NGY10gEA?oc=5" target="_blank">Fed unleashes another big rate hike in bid to curb inflation</a>&nbsp;&nbsp;<font color="#6f6f6f">The Associated Press</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vZmluYW5jZS55YWhvby5jb20vbmV3cy9mZWRlcmFsLXJlc2VydmUtaW50ZXJlc3QtcmF0ZXMtZm9tYy1tb25ldGFyeS1wb2xpY3ktZGVjaXNpb24tanVseS0yMDIyLTE0MDU0MDI2NS5odG1s0gEA?oc=5" target="_blank">Federal Reserve raises interest rates by 0.75%, matching June's historic move</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo Finance</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MEdZMnB6UWJELW_SAQA?oc=5" target="_blank">U.S. stocks rally after Fed rate hike</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvZmVkLWludGVyZXN0LXJhdGUtaGlrZS13aGF0LXdpbGwtYmUtbW9yZS1leHBlbnNpdmUuaHRtbNIBAA?oc=5" target="_blank">The Fed just raised interest rates by another 0.75%—here are 5 things that will be more expensive</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVmh0dHBzOi8vd3d3LnJldXRlcnMuY29tL21hcmtldHMvdXMvZmVkLWhpa2VzLXJhdGVzLWFub3RoZXItNzUtYmFzaXMtcG9pbnRzLTIwMjItMDctMjcv0gEA?oc=5" target="_blank">Reactions after Fed hikes rates by another 75 basis points</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2poOEx2UEJSRjdoWEN4RlhPODB5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + The Associated Press + + + $25 Million Lawsuit Filed Over Sesame Place Accusations - NBC 10 Philadelphia + https://news.google.com/__i/rss/rd/articles/CBMiamh0dHBzOi8vd3d3Lm5iY3BoaWxhZGVscGhpYS5jb20vbmV3cy9sb2NhbC8yNS1taWxsaW9uLWxhd3N1aXQtZmlsZWQtb3Zlci1zZXNhbWUtcGxhY2UtYWNjdXNhdGlvbnMvMzMxNzc2OS_SAXBodHRwczovL3d3dy5uYmNwaGlsYWRlbHBoaWEuY29tL25ld3MvbG9jYWwvMjUtbWlsbGlvbi1sYXdzdWl0LWZpbGVkLW92ZXItc2VzYW1lLXBsYWNlLWFjY3VzYXRpb25zLzMzMTc3NjkvP2FtcD0x?oc=5 + 1515836196 + Thu, 28 Jul 2022 01:14:32 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiamh0dHBzOi8vd3d3Lm5iY3BoaWxhZGVscGhpYS5jb20vbmV3cy9sb2NhbC8yNS1taWxsaW9uLWxhd3N1aXQtZmlsZWQtb3Zlci1zZXNhbWUtcGxhY2UtYWNjdXNhdGlvbnMvMzMxNzc2OS_SAXBodHRwczovL3d3dy5uYmNwaGlsYWRlbHBoaWEuY29tL25ld3MvbG9jYWwvMjUtbWlsbGlvbi1sYXdzdWl0LWZpbGVkLW92ZXItc2VzYW1lLXBsYWNlLWFjY3VzYXRpb25zLzMzMTc3NjkvP2FtcD0x?oc=5" target="_blank">$25 Million Lawsuit Filed Over Sesame Place Accusations</a>&nbsp;&nbsp;<font color="#6f6f6f">NBC 10 Philadelphia</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy91cy9waGlsYWRlbHBoaWEtc2Vhd29ybGQtc2VzYW1lLXBsYWNlLXN1aXQtcmVhai9pbmRleC5odG1s0gFdaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy91cy9waGlsYWRlbHBoaWEtc2Vhd29ybGQtc2VzYW1lLXBsYWNlLXN1aXQtcmVhai9pbmRleC5odG1s?oc=5" target="_blank">Family sues SeaWorld's Sesame Place Philadelphia for alleged racist interaction</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vd3d3LmlucXVpcmVyLmNvbS9jb2x1bW5pc3RzL3Nlc2FtZS1wbGFjZS1yb3NpdGEtcmFjaXNtLTIwMjIwNzI3Lmh0bWzSAQA?oc=5" target="_blank">Sesame Place staff needs more than just DEI training</a>&nbsp;&nbsp;<font color="#6f6f6f">The Philadelphia Inquirer</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiswFodHRwczovL3d3dy5idWNrc2NvdW50eWNvdXJpZXJ0aW1lcy5jb20vc3RvcnkvbmV3cy9sb2NhbC8yMDIyLzA3LzI3L3Nlc2FtZS1wbGFjZS1yb3NpdGEtam9kaS1icm93bi1yYWNlLWJsYWNrLW1pZGRsZXRvd24tYnVja3MtY291bnR5LWxhbmdob3JuZS1kaXNjcmltaW5hdGlvbi1sYXdzdWl0LzY1Mzg0NjcwMDA3L9IBAA?oc=5" target="_blank">Maryland dad sues Sesame Place alleging characters snubbed his child</a>&nbsp;&nbsp;<font color="#6f6f6f">Bucks County Courier Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWmh0dHBzOi8vNmFiYy5jb20vc2VzYW1lLXBsYWNlLWxhd3N1aXQtdmlyYWwtdmlkZW8tcm9zaXRhLWNoYXJhY3Rlci1yYWNpc20tY2xhaW1zLzEyMDc3MTE4L9IBXmh0dHBzOi8vNmFiYy5jb20vYW1wL3Nlc2FtZS1wbGFjZS1sYXdzdWl0LXZpcmFsLXZpZGVvLXJvc2l0YS1jaGFyYWN0ZXItcmFjaXNtLWNsYWltcy8xMjA3NzExOC8?oc=5" target="_blank">Law firm files class action lawsuit against Sesame Place following claims of racial bias at Langhorne, Pennsylvania park</a>&nbsp;&nbsp;<font color="#6f6f6f">WPVI-TV</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lrcHVmU0JSSFZRMlR4QjhaNUVTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + NBC 10 Philadelphia + + + With Roe Gone, Republicans Quarrel Over How Far to Push Abortion Bans - The New York Times + https://news.google.com/__i/rss/rd/articles/CBMiO2h0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvdXMvaW5kaWFuYS1hYm9ydGlvbi5odG1s0gEA?oc=5 + 1502039184 + Wed, 27 Jul 2022 22:20:31 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiO2h0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvdXMvaW5kaWFuYS1hYm9ydGlvbi5odG1s0gEA?oc=5" target="_blank">With Roe Gone, Republicans Quarrel Over How Far to Push Abortion Bans</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9bjNMY0YzdFNWckXSAQA?oc=5" target="_blank">Signs of the Times | Protestors fight for their side at Indiana statehouse</a>&nbsp;&nbsp;<font color="#6f6f6f">WTHR</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMigQFodHRwczovL3d3dy5pbmR5c3Rhci5jb20vc3Rvcnkvb3Bpbmlvbi8yMDIyLzA3LzI2L3doeS1pbmRpYW5hLWxlZ2lzbGF0b3JzLXNob3VsZC1saXN0ZW4tdG8tYWxsLXZvaWNlcy1hYm91dC1hYm9ydGlvbi82NTM4MTQxNDAwNy_SAQA?oc=5" target="_blank">Why Indiana legislators should listen to all voices about abortion</a>&nbsp;&nbsp;<font color="#6f6f6f">IndyStar</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9anVvLUt1QkpnemfSAQA?oc=5" target="_blank">Legal experts, doctors raise concerns about Indiana abortion bill</a>&nbsp;&nbsp;<font color="#6f6f6f">FOX59 News</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lRbVozTUJSSDk5N0F4YXM3c1V5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + The New York Times + + + Hundreds of protesters storm Iraq parliament in support of cleric Moqtada al-Sadr - The Guardian + https://news.google.com/__i/rss/rd/articles/CBMif2h0dHBzOi8vd3d3LnRoZWd1YXJkaWFuLmNvbS93b3JsZC8yMDIyL2p1bC8yOC9odW5kcmVkcy1vZi1wcm90ZXN0ZXJzLXN0b3JtLWlyYXEtcGFybGlhbWVudC1pbi1zdXBwb3J0LW9mLWNsZXJpYy1tb3F0YWRhLWFsLXNhZHLSAQA?oc=5 + 1515858969 + Thu, 28 Jul 2022 01:47:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMif2h0dHBzOi8vd3d3LnRoZWd1YXJkaWFuLmNvbS93b3JsZC8yMDIyL2p1bC8yOC9odW5kcmVkcy1vZi1wcm90ZXN0ZXJzLXN0b3JtLWlyYXEtcGFybGlhbWVudC1pbi1zdXBwb3J0LW9mLWNsZXJpYy1tb3F0YWRhLWFsLXNhZHLSAQA?oc=5" target="_blank">Hundreds of protesters storm Iraq parliament in support of cleric Moqtada al-Sadr</a>&nbsp;&nbsp;<font color="#6f6f6f">The Guardian</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WWhMVkxDZGtEbmfSAQA?oc=5" target="_blank">Hundreds Of Protesters Storm Iraqi Parliament</a>&nbsp;&nbsp;<font color="#6f6f6f">NBC News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWmh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9taWRkbGVlYXN0L2lyYXEtcHJvdGVzdHMtYmFnaGRhZC1ncmVlbi16b25lLWludGwvaW5kZXguaHRtbNIBXmh0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvbWlkZGxlZWFzdC9pcmFxLXByb3Rlc3RzLWJhZ2hkYWQtZ3JlZW4tem9uZS1pbnRsL2luZGV4Lmh0bWw?oc=5" target="_blank">Iraqi protesters break into parliament denouncing the nomination of new premier</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZWh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vbmV3cy8yMDIyLzcvMjcvaXJhcWktcHJvdGVzdGVycy1zdG9ybS1wYXJsaWFtZW50LW11cXRhZGEtYWwtc2Fkci1ncmVlbi16b25l0gFpaHR0cHM6Ly93d3cuYWxqYXplZXJhLmNvbS9hbXAvbmV3cy8yMDIyLzcvMjcvaXJhcWktcHJvdGVzdGVycy1zdG9ybS1wYXJsaWFtZW50LW11cXRhZGEtYWwtc2Fkci1ncmVlbi16b25l?oc=5" target="_blank">Iraqi protesters storm the parliament in Baghdad’s Green Zone</a>&nbsp;&nbsp;<font color="#6f6f6f">Al Jazeera English</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2laMk9qU0JSR2xSTHhPeU5naDJ5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + The Guardian + + + Japanese monkeys stealing babies, clawing at flesh, Yamaguchi city officials say - KABC-TV + https://news.google.com/__i/rss/rd/articles/CBMiR2h0dHBzOi8vYWJjNy5jb20vbW9ua2V5cy1hdHRhY2stamFwYW4tdG9reW8tYW5pbWFscy15YW1hZ3VjaGkvMTIwNzY5MzEv0gFLaHR0cHM6Ly9hYmM3LmNvbS9hbXAvbW9ua2V5cy1hdHRhY2stamFwYW4tdG9reW8tYW5pbWFscy15YW1hZ3VjaGkvMTIwNzY5MzEv?oc=5 + 1505579795 + Thu, 28 Jul 2022 02:01:14 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiR2h0dHBzOi8vYWJjNy5jb20vbW9ua2V5cy1hdHRhY2stamFwYW4tdG9reW8tYW5pbWFscy15YW1hZ3VjaGkvMTIwNzY5MzEv0gFLaHR0cHM6Ly9hYmM3LmNvbS9hbXAvbW9ua2V5cy1hdHRhY2stamFwYW4tdG9reW8tYW5pbWFscy15YW1hZ3VjaGkvMTIwNzY5MzEv?oc=5" target="_blank">Japanese monkeys stealing babies, clawing at flesh, Yamaguchi city officials say</a>&nbsp;&nbsp;<font color="#6f6f6f">KABC-TV</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiUWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3dvcmxkL2phcGFuZXNlLWNpdHktdW5kZXItYXR0YWNrLXZpb2xlbnQtbW9ua2V5cy1zby1zbWFydNIBAA?oc=5" target="_blank">Japanese city under attack by violent monkeys: 'They are so smart'</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MWw2cHhma0RKbVXSAQA?oc=5" target="_blank">Japanese city alarmed by biting, clawing, attacking monkeys</a>&nbsp;&nbsp;<font color="#6f6f6f">WGN News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiamh0dHBzOi8vd3d3LnRoZWRhaWx5YmVhc3QuY29tL2phcGFuZXNlLW1vbmtleS1nYW5nLWxlYWRlci1raWxsZWQtYWZ0ZXItZG96ZW5zLW9mLXZpY2lvdXMtYXR0YWNrcy1vbi1sb2NhbHPSAQA?oc=5" target="_blank">Japanese Monkey Gang Leader Killed After Dozens of Vicious Attacks on Locals</a>&nbsp;&nbsp;<font color="#6f6f6f">The Daily Beast</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lUcHZYTkJSRWJhdXh0bjNraXl5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + KABC-TV + + + Russia tells NASA space station pullout less imminent than indicated earlier - Reuters + https://news.google.com/__i/rss/rd/articles/CBMid2h0dHBzOi8vd3d3LnJldXRlcnMuY29tL2J1c2luZXNzL2Flcm9zcGFjZS1kZWZlbnNlL3J1c3NpYS1uYXNhLXN0aWNraW5nLXdpdGgtc3BhY2Utc3RhdGlvbi11bnRpbC1sZWFzdC0yMDI4LTIwMjItMDctMjcv0gEA?oc=5 + 1514386381 + Thu, 28 Jul 2022 01:38:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMid2h0dHBzOi8vd3d3LnJldXRlcnMuY29tL2J1c2luZXNzL2Flcm9zcGFjZS1kZWZlbnNlL3J1c3NpYS1uYXNhLXN0aWNraW5nLXdpdGgtc3BhY2Utc3RhdGlvbi11bnRpbC1sZWFzdC0yMDI4LTIwMjItMDctMjcv0gEA?oc=5" target="_blank">Russia tells NASA space station pullout less imminent than indicated earlier</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9aERnMU8xMU5Ed0XSAQA?oc=5" target="_blank">Russia says it will withdraw from the International Space Station after 2024</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS90ZWNobm9sb2d5LzIwMjIvMDcvMjcvbmFzYS1zcGFjZS1zdGF0aW9uLXJ1c3NpYS_SAQA?oc=5" target="_blank">NASA hopes to keep ISS operating despite Russia pullout threat</a>&nbsp;&nbsp;<font color="#6f6f6f">The Washington Post</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9cVg1NExnUHRxa0HSAQA?oc=5" target="_blank">'It's an opportunity for NASA': Russia announces ISS withdrawal</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vcHJvZ3JhbS9pbnNpZGUtc3RvcnkvMjAyMi83LzI3L3doYXRzLXRoZS1mdXR1cmUtb2YtdGhlLWludGVybmF0aW9uYWwtc3BhY2Utc3RhdGlvbtIBcGh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vYW1wL3Byb2dyYW0vaW5zaWRlLXN0b3J5LzIwMjIvNy8yNy93aGF0cy10aGUtZnV0dXJlLW9mLXRoZS1pbnRlcm5hdGlvbmFsLXNwYWNlLXN0YXRpb24?oc=5" target="_blank">What’s the future of the International Space Station?</a>&nbsp;&nbsp;<font color="#6f6f6f">Al Jazeera English</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pONTQ3U0JSSG5mOHNiM3lEZ2dDZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Reuters + + + Ukraine warns Kremlin to 'retreat or be annihilated' in Kherson; US pushing deal to free Griner: Live updates - USA TODAY + https://news.google.com/__i/rss/rd/articles/CBMiXWh0dHBzOi8vd3d3LnVzYXRvZGF5LmNvbS9zdG9yeS9uZXdzL3dvcmxkLzIwMjIvMDcvMjcvdWtyYWluZS1ydXNzaWEtbGl2ZS11cGRhdGVzLzEwMTYwODM0MDAyL9IBAA?oc=5 + 1507711616 + Wed, 27 Jul 2022 22:52:30 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXWh0dHBzOi8vd3d3LnVzYXRvZGF5LmNvbS9zdG9yeS9uZXdzL3dvcmxkLzIwMjIvMDcvMjcvdWtyYWluZS1ydXNzaWEtbGl2ZS11cGRhdGVzLzEwMTYwODM0MDAyL9IBAA?oc=5" target="_blank">Ukraine warns Kremlin to 'retreat or be annihilated' in Kherson; US pushing deal to free Griner: Live updates</a>&nbsp;&nbsp;<font color="#6f6f6f">USA TODAY</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZWh0dHBzOi8vd3d3LmZveG5ld3MuY29tL3dvcmxkL3VrcmFpbmUtdGFrZXMtb3V0LWtleS1icmlkZ2UtZGVzdHJveWluZy1ydXNzaWFuLXBsYW5zLXNvdXRoLWFkdmFuY2VtZW500gEA?oc=5" target="_blank">Ukraine takes out key bridge 'destroying' Russian plans for south 'advancement'</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9c1lEbFhqejR3c1nSAQA?oc=5" target="_blank">Ukraine Targets Bridge Used By Russian Forces For Supplies</a>&nbsp;&nbsp;<font color="#6f6f6f">9NEWS</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQGh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvcnVzc2lhLXVrcmFpbmUtbGl2ZS11cGRhdGVzLmh0bWzSAQA?oc=5" target="_blank">Ukrainian ports prepare to restart grain shipments; U.S. makes offer for release of detained Americans Griner and Whelan</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vbmV3cy55YWhvby5jb20vdWtyYWluaWFuLWFybWVkLWZvcmNlcy1jb25maXJtLWtoZXJzb24tMDYxNzAxMzg0Lmh0bWzSAVRodHRwczovL25ld3MueWFob28uY29tL2FtcGh0bWwvdWtyYWluaWFuLWFybWVkLWZvcmNlcy1jb25maXJtLWtoZXJzb24tMDYxNzAxMzg0Lmh0bWw?oc=5" target="_blank">Ukrainian Armed Forces confirm that Kherson bridge destroyed in high-precision strike</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo News</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lBdGZmT0JSSF91MW1EMGtCTGdTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + USA TODAY + + + Spirit and Frontier Airlines throw out merger agreement - The Verge + https://news.google.com/__i/rss/rd/articles/CBMiZ2h0dHBzOi8vd3d3LnRoZXZlcmdlLmNvbS8yMDIyLzcvMjcvMjMyODEyOTAvc3Bpcml0LWFpcmxpbmVzLWZyb250aWVyLXRocm93LW91dC1tZXJnZXItYWdyZWVtZW50LWpldGJsdWXSAQA?oc=5 + 1514592330 + Wed, 27 Jul 2022 22:09:45 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZ2h0dHBzOi8vd3d3LnRoZXZlcmdlLmNvbS8yMDIyLzcvMjcvMjMyODEyOTAvc3Bpcml0LWFpcmxpbmVzLWZyb250aWVyLXRocm93LW91dC1tZXJnZXItYWdyZWVtZW50LWpldGJsdWXSAQA?oc=5" target="_blank">Spirit and Frontier Airlines throw out merger agreement</a>&nbsp;&nbsp;<font color="#6f6f6f">The Verge</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMicmh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvc3Bpcml0LWFpcmxpbmVzLWZyb250aWVyLXRlcm1pbmF0ZS1kZWFsLXRoYXQtd2FzLW1hcnJlZC1ieS1qZXRibHVlcy1yaXZhbC1iaWQuaHRtbNIBAA?oc=5" target="_blank">Spirit ends merger agreement with Frontier, continues takeover talks with JetBlue</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiP2h0dHBzOi8vd3d3LmZ0LmNvbS9jb250ZW50LzEwNTQyZTVkLWYyN2UtNDIxMi05MzhkLTNiNjk1NmM2ZWIwOdIBAA?oc=5" target="_blank">Live news updates: Ford reaffirms outlook as sales rebound, but acknowledges inflationary pressures</a>&nbsp;&nbsp;<font color="#6f6f6f">Financial Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LmJsb29tYmVyZy5jb20vb3Bpbmlvbi9hcnRpY2xlcy8yMDIyLTA3LTI3L3NwaXJpdC1mb3JjZWQtdG8tbGlzdGVuLXRvLWludmVzdG9ycy1hbmQtZHVtcC1mcm9udGllctIBAA?oc=5" target="_blank">Spirit Forced to Listen to Investors and Dump Frontier</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9bDVLZXhMdzJMQlnSAQA?oc=5" target="_blank">Spirit Airlines shareholders weigh merger with Frontier as JetBlue pitches rival offer</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pLc0p2U0JSR2R5RDVvUnZpTHlpZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + The Verge + + + QCOM Stock: Qualcomm Beats Targets But Misses With Outlook - Investor's Business Daily + https://news.google.com/__i/rss/rd/articles/CBMiZGh0dHBzOi8vd3d3LmludmVzdG9ycy5jb20vbmV3cy90ZWNobm9sb2d5L3Fjb20tc3RvY2stcXVhbGNvbW0tYmVhdHMtdGFyZ2V0cy1idXQtbWlzc2VzLXdpdGgtb3V0bG9vay_SAQA?oc=5 + 1511405469 + Wed, 27 Jul 2022 21:40:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZGh0dHBzOi8vd3d3LmludmVzdG9ycy5jb20vbmV3cy90ZWNobm9sb2d5L3Fjb20tc3RvY2stcXVhbGNvbW0tYmVhdHMtdGFyZ2V0cy1idXQtbWlzc2VzLXdpdGgtb3V0bG9vay_SAQA?oc=5" target="_blank">QCOM Stock: Qualcomm Beats Targets But Misses With Outlook</a>&nbsp;&nbsp;<font color="#6f6f6f">Investor's Business Daily</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQ2h0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvcXVhbGNvbW0tcWNvbS1lYXJuaW5ncy1xMy0yMDIyLmh0bWzSAQA?oc=5" target="_blank">Qualcomm sales rise 37% despite 'challenging macroeconomic environment'</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9N3BIRnUwVWhnTkXSAQA?oc=5" target="_blank">Qualcomm revenues beat, but company issues weak fourth quarter outlook</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC Television</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiY2h0dHBzOi8vd3d3LmZveGJ1c2luZXNzLmNvbS9tYXJrZXRzL3F1YWxjb21tLXJldmVudWUtZm9yZWNhc3QtZGlzYXBwb2ludHMtY29vbGluZy1zbWFydHBob25lLWRlbWFuZNIBAA?oc=5" target="_blank">Qualcomm revenue forecast disappoints on cooling smartphone demand</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox Business</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiW2h0dHBzOi8vZmluYW5jZS55YWhvby5jb20vbmV3cy9xdWFsY29tbS1yZXZlbnVlLWZvcmVjYXN0LWRpc2FwcG9pbnRzLWNvb2xpbmctMjAwMzA4NTE1Lmh0bWzSAWNodHRwczovL2ZpbmFuY2UueWFob28uY29tL2FtcGh0bWwvbmV3cy9xdWFsY29tbS1yZXZlbnVlLWZvcmVjYXN0LWRpc2FwcG9pbnRzLWNvb2xpbmctMjAwMzA4NTE1Lmh0bWw?oc=5" target="_blank">Qualcomm warns of sales hit from cooling smartphone demand</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo Finance</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lkNzlqUUJSR2E3TC02dk9sZW5pZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Investor's Business Daily + + + Ford Earnings Top Estimates as Prices Cliimb - Bloomberg Markets and Finance + https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UHdzNlBIdFJ2d0nSAQA?oc=5 + 1514395396 + Wed, 27 Jul 2022 21:45:26 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UHdzNlBIdFJ2d0nSAQA?oc=5" target="_blank">Ford Earnings Top Estimates as Prices Cliimb</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg Markets and Finance</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiPGh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvZm9yZC1mLWVhcm5pbmdzLXEyLTIwMjIuaHRtbNIBAA?oc=5" target="_blank">Ford beats expectations and raises dividend as company sells more of its top models</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UC02aGlhLU9WSFnSAQA?oc=5" target="_blank">Ford stock tops earnings expectations, revenue exceeds $40 billion</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo Finance</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMib2h0dHBzOi8vd3d3LmF1dG9uZXdzLmNvbS9hdXRvbWFrZXJzLXN1cHBsaWVycy9mb3JkLWVhcm5pbmdzLXEyLW5ldC1pbmNvbWUtcmlzZXMtMTktNjY3LW1pbGxpb24tcmV2ZW51ZS1qdW1wcy01MNIBAA?oc=5" target="_blank">Ford generates $667 million in Q2 net income as revenue jumps 50%</a>&nbsp;&nbsp;<font color="#6f6f6f">Automotive News</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lFcm9fU0JSRnR1QVFsZ2thTTZ5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Bloomberg Markets and Finance + + + Fed Watchers Say Markets Got It All Wrong on Powell 'Pivot' - Bloomberg + https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LmJsb29tYmVyZy5jb20vbmV3cy9hcnRpY2xlcy8yMDIyLTA3LTI3L2ZlZC13YXRjaGVycy1zYXktbWFya2V0cy1nb3QtaXQtYWxsLXdyb25nLW9uLXBvd2VsbC1waXZvdNIBAA?oc=5 + 1504405744 + Wed, 27 Jul 2022 22:09:58 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LmJsb29tYmVyZy5jb20vbmV3cy9hcnRpY2xlcy8yMDIyLTA3LTI3L2ZlZC13YXRjaGVycy1zYXktbWFya2V0cy1nb3QtaXQtYWxsLXdyb25nLW9uLXBvd2VsbC1waXZvdNIBAA?oc=5" target="_blank">Fed Watchers Say Markets Got It All Wrong on Powell 'Pivot'</a>&nbsp;&nbsp;<font color="#6f6f6f">Bloomberg</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMifGh0dHBzOi8vd3d3Lm1hcmtldHdhdGNoLmNvbS9zdG9yeS9zdXJwcmlzZS1ob3ctdGhlLXN0b2NrLW1hcmtldC1oYXMtcmVhY3RlZC1vbi1lYWNoLWZlZC1kZWNpc2lvbi1kYXktc2luY2UtbWFyY2gtMTE2NTg5MzM5OTPSAQA?oc=5" target="_blank">Surprise? How the stock market has reacted on day of each Fed rate hike in 2022</a>&nbsp;&nbsp;<font color="#6f6f6f">MarketWatch</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYmh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9idXNpbmVzcy9uaWdodGNhcC1mZWQtaW50ZXJlc3QtcmF0ZXMtaW5mbGF0aW9uLXJlY2Vzc2lvbi9pbmRleC5odG1s0gEA?oc=5" target="_blank">The Fed is bushwhacking through uncharted territory</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYWh0dHBzOi8vdGhlaGlsbC5jb20vb3Bpbmlvbi9maW5hbmNlLzM1NzM5NzQtdGhlLXByb2JsZW0td2l0aC1hLXBlcnNpc3RlbnRseS1sYXRlLWZlZGVyYWwtcmVzZXJ2ZS_SAQA?oc=5" target="_blank">The problem with a persistently late Federal Reserve</a>&nbsp;&nbsp;<font color="#6f6f6f">The Hill</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2p3MGEzTkJSRXJlZU5wWmJNbWtpZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Bloomberg + + + Now all Google Nest cameras can stream video to your TV - The Verge + https://news.google.com/__i/rss/rd/articles/CBMiW2h0dHBzOi8vd3d3LnRoZXZlcmdlLmNvbS8yMDIyLzcvMjcvMjMyODE1ODAvZ29vZ2xlLW5lc3QtY2FtLWNocm9tZWNhc3QtZ29vZ2xlLXR2LWxpdmUtdmlkZW_SAQA?oc=5 + 1516036399 + Thu, 28 Jul 2022 00:05:10 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiW2h0dHBzOi8vd3d3LnRoZXZlcmdlLmNvbS8yMDIyLzcvMjcvMjMyODE1ODAvZ29vZ2xlLW5lc3QtY2FtLWNocm9tZWNhc3QtZ29vZ2xlLXR2LWxpdmUtdmlkZW_SAQA?oc=5" target="_blank">Now all Google Nest cameras can stream video to your TV</a>&nbsp;&nbsp;<font color="#6f6f6f">The Verge</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQGh0dHBzOi8vOXRvNWdvb2dsZS5jb20vMjAyMi8wNy8yNy9jaHJvbWVjYXN0LWdvb2dsZS10di1uZXN0LWNhbS_SAQA?oc=5" target="_blank">Chromecast with Google TV finally supports streaming live video from new Nest Cams, Doorbell</a>&nbsp;&nbsp;<font color="#6f6f6f">9to5Google</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRmh0dHBzOi8vd3d3LmVuZ2FkZ2V0LmNvbS9uZXN0LWNocm9tZWNhc3Qtd2l0aC1nb29nbGUtdHYtMjEwMDAxMzQ2Lmh0bWzSAQA?oc=5" target="_blank">Nest cameras can now, at long last, livestream to Chromecast with Google TV</a>&nbsp;&nbsp;<font color="#6f6f6f">Engadget</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vd3d3LmRyb2lkLWxpZmUuY29tLzIwMjIvMDcvMjcvc3RyZWFtLW5lc3QtY2FtLWZlZWRzLXJpZ2h0LXRvLXlvdXItZ29vZ2xlLXR2L9IBAA?oc=5" target="_blank">Stream Nest Cam Feeds Right to Your Google TV</a>&nbsp;&nbsp;<font color="#6f6f6f">Droid Life</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiSGh0dHBzOi8vd3d3LmFuZHJvaWRwb2xpY2UuY29tL25lc3QtbGl2ZS1mZWVkcy1jaHJvbWVjYXN0LXdpdGgtZ29vZ2xlLXR2L9IBAA?oc=5" target="_blank">Embrace your inner Big Brother with Nest live feeds on Chromecast with Google TV</a>&nbsp;&nbsp;<font color="#6f6f6f">Android Police</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2l2d3ZQU0JSR2cwRUZEZFVJUk9TZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + The Verge + + + Reaction: Meta Quest 2's Price Hike Will Have PSVR2 Relieved or Rubbing Its Hands - Push Square + https://news.google.com/__i/rss/rd/articles/CBMic2h0dHBzOi8vd3d3LnB1c2hzcXVhcmUuY29tL2ZlYXR1cmVzL3JlYWN0aW9uLW1ldGEtcXVlc3QtMnMtcHJpY2UtaGlrZS13aWxsLWhhdmUtcHN2cjItcmVsaWV2ZWQtb3ItcnViYmluZy1pdHMtaGFuZHPSAQA?oc=5 + 1510087349 + Wed, 27 Jul 2022 13:00:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMic2h0dHBzOi8vd3d3LnB1c2hzcXVhcmUuY29tL2ZlYXR1cmVzL3JlYWN0aW9uLW1ldGEtcXVlc3QtMnMtcHJpY2UtaGlrZS13aWxsLWhhdmUtcHN2cjItcmVsaWV2ZWQtb3ItcnViYmluZy1pdHMtaGFuZHPSAQA?oc=5" target="_blank">Reaction: Meta Quest 2's Price Hike Will Have PSVR2 Relieved or Rubbing Its Hands</a>&nbsp;&nbsp;<font color="#6f6f6f">Push Square</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiWGh0dHBzOi8vbGlmZWhhY2tlci5jb20vaWYteW91cmUtcGxhbm5pbmctdG8tYnV5LWEtbWV0YS1xdWVzdC0yLWJldHRlci1kby1pdC1mLTE4NDkzMzg2NjLSAQA?oc=5" target="_blank">If You're Planning to Buy a Meta Quest 2, Better Do It Fast</a>&nbsp;&nbsp;<font color="#6f6f6f">Lifehacker</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMimQFodHRwczovL3d3dy5iZW56aW5nYS5jb20vYW5hbHlzdC1yYXRpbmdzL2FuYWx5c3QtY29sb3IvMjIvMDcvMjgyMTg3NDgvbWV0YXMtcXVlc3QtMi1oZWFkc2V0LWhpa2UtbGVhdmVzLWFuYWx5c3Qtd29ycmllZC1hYm91dC10aGUtZ2Vhci1sb3NpbmctY3JpdGljYWwtY2_SAQA?oc=5" target="_blank">Meta's Quest 2 Headset Price Hike Leaves Analyst Worried About The Gear Losing 'Critical Competitive Adva</a>&nbsp;&nbsp;<font color="#6f6f6f">Benzinga</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiOWh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vb3Bpbmlvbi9tZXRhLXF1ZXN0LTItcHJpY2UtaGlrZdIBAA?oc=5" target="_blank">Meta Quest 2 price hike is pure greed — and bad for VR</a>&nbsp;&nbsp;<font color="#6f6f6f">Tom's Guide</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vd3d3Lmlnbi5jb20vYXJ0aWNsZXMveGJveC13aXJlbGVzcy1jb250cm9sbGVyLW1ldGEtcXVlc3QtMi1kYWlseS1kZWFscy03MjcyMtIBAA?oc=5" target="_blank">Daily Deals: Xbox Wireless Controller, Xbox Series X, Meta Quest 2, and More - IGN</a>&nbsp;&nbsp;<font color="#6f6f6f">IGN</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2kxdFlqUUJSRnRPaWtKVzlyT1BpZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Push Square + + + Every Mainline Yakuza Game Is Coming To PlayStation Plus - Kotaku + https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8va290YWt1LmNvbS95YWt1emEtbGlrZS1hLWRyYWdvbi1zb255LXBsYXlzdGF0aW9uLXBsdXMtc2VnYS1rYXp1bWEtMTg0OTM0MDIxONIBAA?oc=5 + 1515467371 + Wed, 27 Jul 2022 22:00:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8va290YWt1LmNvbS95YWt1emEtbGlrZS1hLWRyYWdvbi1zb255LXBsYXlzdGF0aW9uLXBsdXMtc2VnYS1rYXp1bWEtMTg0OTM0MDIxONIBAA?oc=5" target="_blank">Every Mainline Yakuza Game Is Coming To PlayStation Plus</a>&nbsp;&nbsp;<font color="#6f6f6f">Kotaku</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTWh0dHBzOi8vd3d3Lmlnbi5jb20vYXJ0aWNsZXMvcGxheXN0YXRpb24tcGx1cy1nYW1lcy1mb3ItYXVndXN0LTIwMjItYW5ub3VuY2Vk0gEA?oc=5" target="_blank">PlayStation Plus Games for August 2022 Announced - IGN</a>&nbsp;&nbsp;<font color="#6f6f6f">IGN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMikgFodHRwczovL2Jsb2cucGxheXN0YXRpb24uY29tLzIwMjIvMDcvMjcvcGxheXN0YXRpb24tcGx1cy1tb250aGx5LWdhbWVzLWZvci1hdWd1c3QteWFrdXphLWxpa2UtYS1kcmFnb24tdG9ueS1oYXdrcy1wcm8tc2thdGVyLTEyLWxpdHRsZS1uaWdodG1hcmVzL9IBlgFodHRwczovL2Jsb2cucGxheXN0YXRpb24uY29tLzIwMjIvMDcvMjcvcGxheXN0YXRpb24tcGx1cy1tb250aGx5LWdhbWVzLWZvci1hdWd1c3QteWFrdXphLWxpa2UtYS1kcmFnb24tdG9ueS1oYXdrcy1wcm8tc2thdGVyLTEyLWxpdHRsZS1uaWdodG1hcmVzL2FtcC8?oc=5" target="_blank">PlayStation Plus Monthly Games for August: Yakuza: Like A Dragon, Tony Hawk’s Pro Skater 1+2, Little Nightmares</a>&nbsp;&nbsp;<font color="#6f6f6f">PlayStation</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRWh0dHBzOi8vZG90ZXNwb3J0cy5jb20vZ2VuZXJhbC9uZXdzL3BzLWVzc2VudGlhbC1hdWd1c3QtbGluZXVwLWxlYWtlZNIBAA?oc=5" target="_blank">PS+ Essential August lineup leaked</a>&nbsp;&nbsp;<font color="#6f6f6f">Dot Esports</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiamh0dHBzOi8vd3d3LmdhbWVzcG90LmNvbS9hcnRpY2xlcy9wbGF5c3RhdGlvbi1wbHVzLWVzc2VudGlhbC1nYW1lcy1mb3ItYXVndXN0LTIwMjItY29uZmlybWVkLzExMDAtNjUwNTkxNy_SAW5odHRwczovL3d3dy5nYW1lc3BvdC5jb20vYW1wLWFydGljbGVzL3BsYXlzdGF0aW9uLXBsdXMtZXNzZW50aWFsLWdhbWVzLWZvci1hdWd1c3QtMjAyMi1jb25maXJtZWQvMTEwMC02NTA1OTE3Lw?oc=5" target="_blank">PlayStation Plus Essential Games For August 2022 Confirmed</a>&nbsp;&nbsp;<font color="#6f6f6f">GameSpot</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pyNU5EU0JSR05fWUlrYWNaSUJDZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Kotaku + + + Likely camera sensors for Pixel 7, 7 Pro, and Pixel tablet uncovered in code - 9to5Google + https://news.google.com/__i/rss/rd/articles/CBMiRGh0dHBzOi8vOXRvNWdvb2dsZS5jb20vMjAyMi8wNy8yNi9waXhlbC03LXByby10YWJsZXQtY2FtZXJhLXNlbnNvcnMv0gEA?oc=5 + 1514086765 + Tue, 26 Jul 2022 17:13:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRGh0dHBzOi8vOXRvNWdvb2dsZS5jb20vMjAyMi8wNy8yNi9waXhlbC03LXByby10YWJsZXQtY2FtZXJhLXNlbnNvcnMv0gEA?oc=5" target="_blank">Likely camera sensors for Pixel 7, 7 Pro, and Pixel tablet uncovered in code</a>&nbsp;&nbsp;<font color="#6f6f6f">9to5Google</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiS2h0dHBzOi8vd2NjZnRlY2guY29tL3RoZS1nb29nbGUtcGl4ZWwtNy1wcm8tdXNlcy0zLXNhbXN1bmctaXNvY2VsbC1jYW1lcmFzL9IBAA?oc=5" target="_blank">The Google Pixel 7 Pro Uses 3 Samsung ISOCELL Cameras</a>&nbsp;&nbsp;<font color="#6f6f6f">Wccftech</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiemh0dHBzOi8vd3d3LmdzbWFyZW5hLmNvbS9nb29nbGVfcGl4ZWxfN183X3Byb19waXhlbF90YWJsZXRfYW5kX2ZvbGRhYmxlX3NtYXJ0cGhvbmVfY2FtZXJhX3NlbnNvcnNfdW5jb3ZlcmVkLW5ld3MtNTUyMDAucGhw0gF3aHR0cHM6Ly9tLmdzbWFyZW5hLmNvbS9nb29nbGVfcGl4ZWxfN183X3Byb19waXhlbF90YWJsZXRfYW5kX2ZvbGRhYmxlX3NtYXJ0cGhvbmVfY2FtZXJhX3NlbnNvcnNfdW5jb3ZlcmVkLWFtcC01NTIwMC5waHA?oc=5" target="_blank">Google Pixel 7, 7 Pro, Pixel Tablet and Pixel foldable camera sensors uncovered - GSMArena.com news</a>&nbsp;&nbsp;<font color="#6f6f6f">GSMArena.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMic2h0dHBzOi8vd3d3LnBvY2tldC1saW50LmNvbS9waG9uZXMvbmV3cy9nb29nbGUvMTYyMDEzLWdvb2dsZS1waXhlbC03LWFuZC1waXhlbC03LXByby1jYW1lcmEtc2Vuc29yLXNwZWNzLWFyZS1sZWFrZWTSAQA?oc=5" target="_blank">Google Pixel 7 and Pixel 7 Pro camera sensor specs have leaked</a>&nbsp;&nbsp;<font color="#6f6f6f">Pocket-lint</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXmh0dHBzOi8vd3d3LmxhcHRvcG1hZy5jb20vbmV3cy9waXhlbC03LWNhbWVyYS1kZXRhaWxzLWV4cG9zZWQtYW5kLWl0LWNvbWVzLXdpdGgtZmFtaWxpYXItc3BlY3PSAQA?oc=5" target="_blank">Pixel 7 camera details exposed — and it comes with familiar specs</a>&nbsp;&nbsp;<font color="#6f6f6f">Laptop Mag</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2p0d3Z6UkJSRWc0OVpMdjZKZmxpZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + 9to5Google + + + Tony Dow, known for playing Wally Cleaver on "Leave It to Beaver," dead at 77 - CBS News + https://news.google.com/__i/rss/rd/articles/CBMiXGh0dHBzOi8vd3d3LmNic25ld3MuY29tL25ld3MvdG9ueS1kb3ctZGVhZC1hZ2UtNzctYWN0b3Itd2FsbHktY2xlYXZlci1vbi1sZWF2ZS1pdC10by1iZWF2ZXIv0gFgaHR0cHM6Ly93d3cuY2JzbmV3cy5jb20vYW1wL25ld3MvdG9ueS1kb3ctZGVhZC1hZ2UtNzctYWN0b3Itd2FsbHktY2xlYXZlci1vbi1sZWF2ZS1pdC10by1iZWF2ZXIv?oc=5 + 1514657446 + Wed, 27 Jul 2022 23:14:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXGh0dHBzOi8vd3d3LmNic25ld3MuY29tL25ld3MvdG9ueS1kb3ctZGVhZC1hZ2UtNzctYWN0b3Itd2FsbHktY2xlYXZlci1vbi1sZWF2ZS1pdC10by1iZWF2ZXIv0gFgaHR0cHM6Ly93d3cuY2JzbmV3cy5jb20vYW1wL25ld3MvdG9ueS1kb3ctZGVhZC1hZ2UtNzctYWN0b3Itd2FsbHktY2xlYXZlci1vbi1sZWF2ZS1pdC10by1iZWF2ZXIv?oc=5" target="_blank">Tony Dow, known for playing Wally Cleaver on "Leave It to Beaver," dead at 77</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRWh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9lbnRlcnRhaW5tZW50L3RvbnktZG93LW9iaXQvaW5kZXguaHRtbNIBSWh0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvZW50ZXJ0YWlubWVudC90b255LWRvdy1vYml0L2luZGV4Lmh0bWw?oc=5" target="_blank">Tony Dow, 'Leave It to Beaver' star, has died</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiUmh0dHBzOi8vd3d3LmZveG5ld3MuY29tL2VudGVydGFpbm1lbnQvdG9ueS1kb3ctbGVhdmUtYmVhdmVyLXN0YXItZGVhZC1iZXR0ZXItcGxhY2XSAQA?oc=5" target="_blank">Tony Dow, 'Leave It to Beaver' star, dead at 77, son confirms: 'He is in a better place'</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WEJkbGhTNVp1RzjSAQA?oc=5" target="_blank">'Leave it to Beaver' actor Tony Dow dies at 77 | USA TODAY</a>&nbsp;&nbsp;<font color="#6f6f6f">USA TODAY</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L2xlYXZlLWl0LXRvLWJlYXZlci1zdGFyLXRvbnktZG93LWRlYWQtYXQtNzctMi_SAQA?oc=5" target="_blank">'Leave It to Beaver' star Tony Dow dead at 77 after premature announcement</a>&nbsp;&nbsp;<font color="#6f6f6f">New York Post </font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2ltclpfU0JSRWl0Wk8zclNFSmR5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + CBS News + + + Instagram’s head responds to Kylie Jenner, Kim Kardashian sharing petition for app to ‘stop trying to be TikTok’ - Yahoo Life + https://news.google.com/__i/rss/rd/articles/CBMiU2h0dHBzOi8vd3d3LnlhaG9vLmNvbS9saWZlc3R5bGUvaW5zdGFncmFtLWhlYWQtcmVzcG9uZHMta3lsaWUtamVubmVyLTE5MDk1NjQ5NC5odG1s0gFbaHR0cHM6Ly93d3cueWFob28uY29tL2FtcGh0bWwvbGlmZXN0eWxlL2luc3RhZ3JhbS1oZWFkLXJlc3BvbmRzLWt5bGllLWplbm5lci0xOTA5NTY0OTQuaHRtbA?oc=5 + 1508021747 + Wed, 27 Jul 2022 20:48:37 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiU2h0dHBzOi8vd3d3LnlhaG9vLmNvbS9saWZlc3R5bGUvaW5zdGFncmFtLWhlYWQtcmVzcG9uZHMta3lsaWUtamVubmVyLTE5MDk1NjQ5NC5odG1s0gFbaHR0cHM6Ly93d3cueWFob28uY29tL2FtcGh0bWwvbGlmZXN0eWxlL2luc3RhZ3JhbS1oZWFkLXJlc3BvbmRzLWt5bGllLWplbm5lci0xOTA5NTY0OTQuaHRtbA?oc=5" target="_blank">Instagram’s head responds to Kylie Jenner, Kim Kardashian sharing petition for app to ‘stop trying to be TikTok’</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo Life</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVmh0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS90ZWNobm9sb2d5LzIwMjIvMDcvMjcvaW5zdGFncmFtLXZpZGVvLXNoaWZ0LWthcmRhc2hpYW4v0gEA?oc=5" target="_blank">Instagram is shifting to videos. Users, including the Kardashians, aren't happy.</a>&nbsp;&nbsp;<font color="#6f6f6f">The Washington Post</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WFFrTTRBeDlKOWvSAQA?oc=5" target="_blank">Instagram CEO RESPONDS After Kardashian-Jenner Backlash | E! News</a>&nbsp;&nbsp;<font color="#6f6f6f">E! News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibmh0dHBzOi8vd3d3Lmh1ZmZwb3N0LmNvbS9lbnRyeS9raW0ta2FyZGFzaGlhbi1reWxpZS1qZW5uZXItaW5zdGFncmFtLWNoYW5nZXMtdGlrdG9rX25fNjJlMGFkYzJlNGIwYWFkNThkMjBhYzU50gEA?oc=5" target="_blank">Kim Kardashian, Kylie Jenner Blast Instagram Changes: Stop Trying To Be TikTok</a>&nbsp;&nbsp;<font color="#6f6f6f">HuffPost</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2p6cTRyUEJSRmhkTThERlhyaFRpZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Yahoo Life + + + Neil Patrick Harris got final approval of d--k pic used in new show 'Uncoupled' - Page Six + https://news.google.com/__i/rss/rd/articles/CBMiZ2h0dHBzOi8vcGFnZXNpeC5jb20vMjAyMi8wNy8yNy9uZWlsLXBhdHJpY2staGFycmlzLWdvdC1hcHByb3ZhbC1vZi1kaWNrLXBpYy1mb3ItaGlzLW5ldy1zaG93LXVuY291cGxlZC_SAQA?oc=5 + 1511486103 + Wed, 27 Jul 2022 20:49:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZ2h0dHBzOi8vcGFnZXNpeC5jb20vMjAyMi8wNy8yNy9uZWlsLXBhdHJpY2staGFycmlzLWdvdC1hcHByb3ZhbC1vZi1kaWNrLXBpYy1mb3ItaGlzLW5ldy1zaG93LXVuY291cGxlZC_SAQA?oc=5" target="_blank">Neil Patrick Harris got final approval of d--k pic used in new show 'Uncoupled'</a>&nbsp;&nbsp;<font color="#6f6f6f">Page Six</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZkxNdXBBa1NJa0nSAQA?oc=5" target="_blank">Neil Patrick Harris On Getting A Glimpse Of Today's Dating Scene In Show “Uncoupled” | The View</a>&nbsp;&nbsp;<font color="#6f6f6f">The View</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiX2h0dHBzOi8vdHZsaW5lLmNvbS8yMDIyLzA3LzI3L3VuY291cGxlZC1yZXZpZXctbmV0ZmxpeC1uZWlsLXBhdHJpY2staGFycmlzLWdheS1yb21hbnRpYy1jb21lZHkv0gEA?oc=5" target="_blank">Uncoupled Review: Neil Patrick Harris Exposes Himself (Emotionally) in Netflix's Gay Romantic Comedy</a>&nbsp;&nbsp;<font color="#6f6f6f">TVLine</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMia2h0dHBzOi8vcGVvcGxlLmNvbS90di9uZWlsLXBhdHJpY2staGFycmlzLXNheXMtaGlzLTE4LXllYXItcmVsYXRpb25zaGlwLXdpdGgtZGF2aWQtYnVydGthLWlzLWFsbC1pdmUta25vd24v0gEA?oc=5" target="_blank">Neil Patrick Harris on Playing Newly Uncoupled When Love for Husband David Burtka Is 'All I've Known'</a>&nbsp;&nbsp;<font color="#6f6f6f">PEOPLE</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vdmFyaWV0eS5jb20vMjAyMi90di9yZXZpZXdzL3VuY291cGxlZC1uZWlsLXBhdHJpY2staGFycmlzLXJldmlldy0xMjM1MzE4ODczL9IBAA?oc=5" target="_blank">‘Uncoupled’ Is a Surprisingly Sour Neil Patrick Harris Breakup Story: TV Review</a>&nbsp;&nbsp;<font color="#6f6f6f">Variety</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lYNWQzUUJSRWhCQnJza3lXV2RTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Page Six + + + Britney Spears Wins: Judge Denies Jamie Spears’ Motion To Compel Pop Star’s Deposition - Rolling Stone + https://news.google.com/__i/rss/rd/articles/CBMiaWh0dHBzOi8vd3d3LnJvbGxpbmdzdG9uZS5jb20vbXVzaWMvbXVzaWMtbmV3cy9icml0bmV5LXNwZWFycy1jb25zZXJ2YXRvcnNoaXAtamFtaWUtbW90aW9uLWRlbmllZC0xMzg4NTg3L9IBAA?oc=5 + 1507872644 + Wed, 27 Jul 2022 22:49:38 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiaWh0dHBzOi8vd3d3LnJvbGxpbmdzdG9uZS5jb20vbXVzaWMvbXVzaWMtbmV3cy9icml0bmV5LXNwZWFycy1jb25zZXJ2YXRvcnNoaXAtamFtaWUtbW90aW9uLWRlbmllZC0xMzg4NTg3L9IBAA?oc=5" target="_blank">Britney Spears Wins: Judge Denies Jamie Spears’ Motion To Compel Pop Star’s Deposition</a>&nbsp;&nbsp;<font color="#6f6f6f">Rolling Stone</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiaGh0dHBzOi8vd3d3LnRoZWRhaWx5YmVhc3QuY29tL2JyaXRuZXktc3BlYXJzLWNhbi1za2lwLWRlcG9zaXRpb24tYnktZGFkLWphbWllLXNwZWFycy1sYXd5ZXJzLWp1ZGdlLXJ1bGVz0gEA?oc=5" target="_blank">Britney Can Skip Deposition by Dad's Lawyers, Judge Rules</a>&nbsp;&nbsp;<font color="#6f6f6f">The Daily Beast</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiZmh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9lbnRlcnRhaW5tZW50L2JyaXRuZXktc3BlYXJzLW5vdC1kZXBvc2VkLWNvbnNlcnZhdG9yc2hpcC1kYWQvaW5kZXguaHRtbNIBamh0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvZW50ZXJ0YWlubWVudC9icml0bmV5LXNwZWFycy1ub3QtZGVwb3NlZC1jb25zZXJ2YXRvcnNoaXAtZGFkL2luZGV4Lmh0bWw?oc=5" target="_blank">Judge rules Britney Spears will not have to sit for deposition in ongoing legal battle with her father</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lFbjRIUEJSRkFZX1dXTV9YVU1TZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Rolling Stone + + + Yankees Acquire Andrew Benintendi From Royals - MLB Trade Rumors + https://news.google.com/__i/rss/rd/articles/CBMiUGh0dHBzOi8vd3d3Lm1sYnRyYWRlcnVtb3JzLmNvbS8yMDIyLzA3L3lhbmtlZXMtdG8tYWNxdWlyZS1hbmRyZXctYmVuaW50ZW5kaS5odG1s0gEA?oc=5 + 1511353155 + Thu, 28 Jul 2022 03:11:15 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiUGh0dHBzOi8vd3d3Lm1sYnRyYWRlcnVtb3JzLmNvbS8yMDIyLzA3L3lhbmtlZXMtdG8tYWNxdWlyZS1hbmRyZXctYmVuaW50ZW5kaS5odG1s0gEA?oc=5" target="_blank">Yankees Acquire Andrew Benintendi From Royals</a>&nbsp;&nbsp;<font color="#6f6f6f">MLB Trade Rumors</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMikQFodHRwczovL3d3dy5lc3BuLmNvbS9tbGIvc3RvcnkvXy9pZC8zNDMwNDgyMS9uZXcteW9yay15YW5rZWVzLWZpbmFsaXppbmctZGVhbC1hY3F1aXJlLW91dGZpZWxkZXItYW5kcmV3LWJlbmludGVuZGkta2Fuc2FzLWNpdHktcm95YWxzLXNvdXJjZXMtc2F50gGeAWh0dHBzOi8vd3d3LmVzcG4uY29tL21sYi9zdG9yeS9fL2lkLzM0MzA0ODIxL25ldy15b3JrLXlhbmtlZXMtZmluYWxpemluZy1kZWFsLWFjcXVpcmUtb3V0ZmllbGRlci1hbmRyZXctYmVuaW50ZW5kaS1rYW5zYXMtY2l0eS1yb3lhbHMtc291cmNlcy1zYXk_cGxhdGZvcm09YW1w?oc=5" target="_blank">New York Yankees finalizing deal to acquire outfielder Andrew Benintendi from the Kansas City Royals, sources say</a>&nbsp;&nbsp;<font color="#6f6f6f">ESPN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiOGh0dHBzOi8vd3d3Lm1sYi5jb20vbmV3cy9hbmRyZXctYmVuaW50ZW5kaS15YW5rZWVzLXRyYWRl0gEA?oc=5" target="_blank">Andrew Benintendi traded to Yankees</a>&nbsp;&nbsp;<font color="#6f6f6f">MLB.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vd3d3LmthbnNhc2NpdHkuY29tL3Nwb3J0cy9tbGIva2Fuc2FzLWNpdHktcm95YWxzL2FydGljbGUyNjM5MDU4NTcuaHRtbNIBAA?oc=5" target="_blank">KC Royals trade Andrew Benintendi to New York Yankees. Here’s who they’re getting</a>&nbsp;&nbsp;<font color="#6f6f6f">Kansas City Star</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVGh0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L3lhbmtlZXMtdHJhZGUtZm9yLXJveWFscy1vdXRmaWVsZGVyLWFuZHJldy1iZW5pbnRlbmRpL9IBAA?oc=5" target="_blank">Yankees trade for Royals outfielder Andrew Benintendi</a>&nbsp;&nbsp;<font color="#6f6f6f">New York Post </font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pEMXRYUUJSSE5FNnZvRFhUam9DZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + MLB Trade Rumors + + + Nets and Celtics rumors: Kevin Durant, Kyrie Irving, Jaylen Brown, Marcus Smart, Grant Williams - Hoops Hype + https://news.google.com/__i/rss/rd/articles/CBMic2h0dHBzOi8vaG9vcHNoeXBlLmNvbS9saXN0cy9uZXRzLWNlbHRpY3MtcnVtb3JzLWtldmluLWR1cmFudC1reXJpZS1pcnZpbmctamF5bGVuLWJyb3duLW1hcmN1cy1zbWFydC1ncmFudC13aWxsaWFtcy_SAQA?oc=5 + 1508787991 + Thu, 28 Jul 2022 01:21:49 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMic2h0dHBzOi8vaG9vcHNoeXBlLmNvbS9saXN0cy9uZXRzLWNlbHRpY3MtcnVtb3JzLWtldmluLWR1cmFudC1reXJpZS1pcnZpbmctamF5bGVuLWJyb3duLW1hcmN1cy1zbWFydC1ncmFudC13aWxsaWFtcy_SAQA?oc=5" target="_blank">Nets and Celtics rumors: Kevin Durant, Kyrie Irving, Jaylen Brown, Marcus Smart, Grant Williams</a>&nbsp;&nbsp;<font color="#6f6f6f">Hoops Hype</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMimgFodHRwczovL3d3dy5lc3BuLmNvbS9uYmEvc3RvcnkvXy9pZC8zNDMwMDIyOC9ib3N0b24tY2VsdGljcy1qYXlzb24tdGF0dW0tcmVzcG9uZGluZy1rZXZpbi1kdXJhbnQtdHJhZGUtc3BlY3VsYXRpb24tc2F5cy1sb3ZlLW91ci10ZWFtLXJlbHVjdGFudC1wdXQtZ20taGF00gGnAWh0dHBzOi8vd3d3LmVzcG4uY29tL25iYS9zdG9yeS9fL2lkLzM0MzAwMjI4L2Jvc3Rvbi1jZWx0aWNzLWpheXNvbi10YXR1bS1yZXNwb25kaW5nLWtldmluLWR1cmFudC10cmFkZS1zcGVjdWxhdGlvbi1zYXlzLWxvdmUtb3VyLXRlYW0tcmVsdWN0YW50LXB1dC1nbS1oYXQ_cGxhdGZvcm09YW1w?oc=5" target="_blank">Boston Celtics' Jayson Tatum, responding to Kevin Durant trade speculation, says 'I love our team,' doesn't wear GM hat</a>&nbsp;&nbsp;<font color="#6f6f6f">ESPN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vYmxlYWNoZXJyZXBvcnQuY29tL2FydGljbGVzLzEwMDQzNDMxLWhlLXdvbnQtZm9yZ2V0LXRoaXMtYXJlLWNlbHRpY3MtZnVtYmxpbmctcmVsYXRpb25zaGlwLXdpdGgtamF5bGVuLWJyb3du0gGEAWh0dHBzOi8vc3luZGljYXRpb24uYmxlYWNoZXJyZXBvcnQuY29tL2FtcC8xMDA0MzQzMS1oZS13b250LWZvcmdldC10aGlzLWFyZS1jZWx0aWNzLWZ1bWJsaW5nLXJlbGF0aW9uc2hpcC13aXRoLWpheWxlbi1icm93bi5hbXAuaHRtbA?oc=5" target="_blank">'He Won't Forget This': Are Celtics Fumbling Relationship with Jaylen Brown?</a>&nbsp;&nbsp;<font color="#6f6f6f">Bleacher Report</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vY2VsdGljc3dpcmUudXNhdG9kYXkuY29tLzIwMjIvMDcvMjcvbmJhLWJvc3Rvbi1jZWx0aWNzLWpiLWtkLW5ldHMtcG92L9IBAA?oc=5" target="_blank">Should the Brooklyn Nets be interested in trading Kevin Durant to the Boston Celtics for Jaylen Brown?</a>&nbsp;&nbsp;<font color="#6f6f6f">Celtics Wire</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMi3AFodHRwczovL2ZhZGVhd2F5d29ybGQubmV0L25iYS1tZWRpYS9jaGFybGVzLWJhcmtsZXktZ2l2ZXMtaGlzLXRha2Utb24td2h5LWtldmluLWR1cmFudC1yZXF1ZXN0ZWQtYS10cmFkZS1pLWRvbnQta25vdy13aGF0cy1nb2luZy1vbi1iZWhpbmQtdGhlLXNjZW5lcy1idXQtaXQtc291bmRzLWxpa2UtaGUtanVzdC1oYWQtZW5vdWdoLW9mLWt5cmllLXRoYXRzLW15LWhvbmVzdC1vcGluaW9u0gHhAWh0dHBzOi8vZmFkZWF3YXl3b3JsZC5uZXQvLmFtcC9uYmEtbWVkaWEvY2hhcmxlcy1iYXJrbGV5LWdpdmVzLWhpcy10YWtlLW9uLXdoeS1rZXZpbi1kdXJhbnQtcmVxdWVzdGVkLWEtdHJhZGUtaS1kb250LWtub3ctd2hhdHMtZ29pbmctb24tYmVoaW5kLXRoZS1zY2VuZXMtYnV0LWl0LXNvdW5kcy1saWtlLWhlLWp1c3QtaGFkLWVub3VnaC1vZi1reXJpZS10aGF0cy1teS1ob25lc3Qtb3Bpbmlvbg?oc=5" target="_blank">Charles Barkley Gives His Take On Why Kevin Durant Requested A Trade: "I Don't Know What's Going On Behind The Scenes But It Sounds Like He Just Had Enough Of Kyrie, That's My Honest Opinion."</a>&nbsp;&nbsp;<font color="#6f6f6f">Fadeaway World</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lYanJuUEJSRm9yMmhOVWFLSlFpZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Hoops Hype + + + Mets sweep Yankees with walk-off win after Max Scherzer dominates - New York Post + https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L21ldHMtZ2V0LXdhbGstb2ZmLXdpbi10by10b3AteWFua2Vlcy1zd2VlcC1zdWJ3YXktc2VyaWVzL9IBAA?oc=5 + 1513586573 + Thu, 28 Jul 2022 02:37:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L21ldHMtZ2V0LXdhbGstb2ZmLXdpbi10by10b3AteWFua2Vlcy1zd2VlcC1zdWJ3YXktc2VyaWVzL9IBAA?oc=5" target="_blank">Mets sweep Yankees with walk-off win after Max Scherzer dominates</a>&nbsp;&nbsp;<font color="#6f6f6f">New York Post </font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9emZmdTdSV2hOcGfSAQA?oc=5" target="_blank">Yankees vs. Mets Game Highlights (7/26/22) | MLB Highlights</a>&nbsp;&nbsp;<font color="#6f6f6f">MLB</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMilQFodHRwczovL3d3dy5tc24uY29tL2VuLXVzL3Nwb3J0cy9tbGIvc3Vid2F5LXNlcmllcy1oYXMtbmV3LXlvcmstYmFzZWJhbGwtZmFucy1kcmVhbWluZy1vZi1hLXlhbmtlZXMtbWV0cy13b3JsZC1zZXJpZXMtb3Bpbmlvbi9hci1BQTEwMWxhej9saT1CQjE1bXM1cdIBAA?oc=5" target="_blank">Subway Series has New York baseball fans dreaming of a Yankees-Mets World Series | Opinion</a>&nbsp;&nbsp;<font color="#6f6f6f">msnNOW</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vbnlwb3N0LmNvbS8yMDIyLzA3LzI3L3lhbmtlZXMtdnMtbWV0cy1zdWJ3YXktc2VyaWVzLTIwMjItZ2FtZS0yLWxpdmUtdXBkYXRlcy_SAQA?oc=5" target="_blank">Subway Series live updates: Starling Marte's walk-off single gives Mets sweep over Yankees</a>&nbsp;&nbsp;<font color="#6f6f6f">New York Post </font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vZGFpbHlrbmlja3MuY29tLzIwMjIvMDcvMjcvZG9ub3Zhbi1taXRjaGVsbC1zdWJ3YXktc2VyaWVzLWVhZ2VyLWtuaWNrcy10cmFkZS_SAQA?oc=5" target="_blank">Donovan Mitchell’s presence at Subway Series makes fans more eager for Knicks trade</a>&nbsp;&nbsp;<font color="#6f6f6f">Daily Knicks</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lOXzkzUkJSRlVzeDYzWHJjcjJDZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + New York Post + + + Mavi Garcia hit by own team car on hectic Tour de France Femmes gravel stage - Cyclingnews + https://news.google.com/__i/rss/rd/articles/CBMibmh0dHBzOi8vd3d3LmN5Y2xpbmduZXdzLmNvbS9uZXdzL21hdmktZ2FyY2lhLWhpdC1ieS1vd24tdGVhbS1jYXItb24taGVjdGljLXRvdXItZGUtZnJhbmNlLWZlbW1lcy1ncmF2ZWwtc3RhZ2Uv0gEA?oc=5 + 1495250451 + Wed, 27 Jul 2022 15:03:50 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibmh0dHBzOi8vd3d3LmN5Y2xpbmduZXdzLmNvbS9uZXdzL21hdmktZ2FyY2lhLWhpdC1ieS1vd24tdGVhbS1jYXItb24taGVjdGljLXRvdXItZGUtZnJhbmNlLWZlbW1lcy1ncmF2ZWwtc3RhZ2Uv0gEA?oc=5" target="_blank">Mavi Garcia hit by own team car on hectic Tour de France Femmes gravel stage</a>&nbsp;&nbsp;<font color="#6f6f6f">Cyclingnews</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVWh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvc3BvcnRzL2N5Y2xpbmcvdG91ci1kZS1mcmFuY2UtZmVtYWxlLWN5Y2xpc3RzLmh0bWzSAQA?oc=5" target="_blank">At Tour de France Femmes, It’s a Steep Climb to Equality</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9US16dmQ1T01qbzTSAQA?oc=5" target="_blank">Riders Left In The Dust On The Gravel | Tour De France Femmes avec Zwift 2022 Stage 4 Highlights</a>&nbsp;&nbsp;<font color="#6f6f6f">GCN Racing</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYGh0dHBzOi8vd3d3LnZlbG9uZXdzLmNvbS9nYWxsZXJ5L2Rpc3BhdGNoLWRlcy1mZW1tZXMtdGhlLWNyb3dkcy1oYXZlLWJlZW4tdGhlLWljaW5nLW9uLXRoZS1jYWtlL9IBAA?oc=5" target="_blank">Dispatch des Femmes: The crowds have been the icing on the cake</a>&nbsp;&nbsp;<font color="#6f6f6f">VeloNews</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXmh0dHBzOi8vY3ljbGluZ3RpcHMuY29tLzIwMjIvMDcvYS1uaWdodG1hcmUtZm9yLWdhcmNpYS1hcy1vdGhlci1nYy1mYXZvdXJpdGVzLXRhbWUtdGhlLWdyYXZlbC_SAQA?oc=5" target="_blank">A nightmare for García as other GC favourites tame the gravel</a>&nbsp;&nbsp;<font color="#6f6f6f">CyclingTips</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lUN1A3SUJSSGJzN0hOWlhKTG9pZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Cyclingnews + + + NASA Will Send More Helicopters to Mars - The New York Times + https://news.google.com/__i/rss/rd/articles/CBMiSGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvc2NpZW5jZS9tYXJzLXNhbXBsZS1taXNzaW9uLW5hc2EuaHRtbNIBAA?oc=5 + CAIiEI9keqP3zduvrqUihhwXI8oqFwgEKg8IACoHCAowjuuKAzCWrzwwt4QY + Wed, 27 Jul 2022 22:46:18 GMT + <a href="https://news.google.com/__i/rss/rd/articles/CBMiSGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvc2NpZW5jZS9tYXJzLXNhbXBsZS1taXNzaW9uLW5hc2EuaHRtbNIBAA?oc=5" target="_blank">NASA Will Send More Helicopters to Mars</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lPZ3VfU0JSSGl2b3hmS3BONjl5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong> + The New York Times + + + Gravitas: Out-of-control Chinese rocket to crash on earth - WION + https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MlI1NzhwYW1USjTSAQA?oc=5 + 1509467665 + Wed, 27 Jul 2022 18:53:35 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MlI1NzhwYW1USjTSAQA?oc=5" target="_blank">Gravitas: Out-of-control Chinese rocket to crash on earth</a>&nbsp;&nbsp;<font color="#6f6f6f">WION</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vd3d3LnlhaG9vLmNvbS9uZXdzL2NoaW5hLXNwYWNlY3JhZnQtcmV0dXJucy1hbWlkLWJvb3N0ZXItMTA1MjI2MTMzLmh0bWzSAVhodHRwczovL25ld3MueWFob28uY29tL2FtcGh0bWwvbmV3cy9jaGluYS1zcGFjZWNyYWZ0LXJldHVybnMtYW1pZC1ib29zdGVyLTEwNTIyNjEzMy5odG1s?oc=5" target="_blank">China spacecraft returns amid booster rocket concerns</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo! Voices</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibmh0dHBzOi8vd3d3LnJldXRlcnMuY29tL2xpZmVzdHlsZS9zY2llbmNlL2NoaW5hLWNsb3NlbHktdHJhY2tpbmctcmVtbmFudHMtaXRzLW1vc3QtcG93ZXJmdWwtcm9ja2V0LTIwMjItMDctMjcv0gEA?oc=5" target="_blank">China closely tracking debris of its most powerful rocket</a>&nbsp;&nbsp;<font color="#6f6f6f">Reuters</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiUmh0dHBzOi8vZ2l6bW9kby5jb20vY2hpbmEtb3V0LW9mLWNvbnRyb2wtcm9ja2V0LXByZWRpY3RlZC1jcmFzaC1qdWx5LTMxLTE4NDkzMzcyOTnSAQA?oc=5" target="_blank">China’s Out-of-Control Rocket Predicted to Crash on July 30 [Updating]</a>&nbsp;&nbsp;<font color="#6f6f6f">Gizmodo</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMibGh0dHBzOi8vd3d3LnRoZWRhaWx5YmVhc3QuY29tL2NoaW5lc2Utcm9ja2V0LXdpbGwtY3Jhc2gtaW50by1lYXJ0aC1zdW5kYXlwb3NzaWJseS1pbnRvLWEtcG9wdWxhdGVkLWNvbW11bml0edIBAA?oc=5" target="_blank">Chinese Rocket Will Crash Into Earth Sunday, Possibly Into a Populated Community</a>&nbsp;&nbsp;<font color="#6f6f6f">The Daily Beast</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lSek9MUEJSR3dCN3JuRkNHVDJ5Z0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + WION + + + Four revelations from the Webb telescope about distant galaxies - Nature.com + https://news.google.com/__i/rss/rd/articles/CBMiMmh0dHBzOi8vd3d3Lm5hdHVyZS5jb20vYXJ0aWNsZXMvZDQxNTg2LTAyMi0wMjA1Ni010gEA?oc=5 + 1514642335 + Wed, 27 Jul 2022 16:42:46 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiMmh0dHBzOi8vd3d3Lm5hdHVyZS5jb20vYXJ0aWNsZXMvZDQxNTg2LTAyMi0wMjA1Ni010gEA?oc=5" target="_blank">Four revelations from the Webb telescope about distant galaxies</a>&nbsp;&nbsp;<font color="#6f6f6f">Nature.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9MUhYN0RwMHprbVnSAQA?oc=5" target="_blank">James Webb space telescope: Why NASA is being pressured to change its name | WION Originals</a>&nbsp;&nbsp;<font color="#6f6f6f">WION</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vd3d3LnNwYWNlLmNvbS9qYW1lcy13ZWJiLXNwYWNlLXRlbGVzY29wZS1maXJzdC1zdXBlcm1hc3NpdmUtYmxhY2staG9sZXPSAQA?oc=5" target="_blank">The James Webb Space Telescope is on the hunt for the universe's 1st-ever supermassive black holes</a>&nbsp;&nbsp;<font color="#6f6f6f">Space.com</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidGh0dHBzOi8vd3d3LmJvc3Rvbmdsb2JlLmNvbS8yMDIyLzA3LzI2L29waW5pb24vamFtZXMtd2ViYi1zcGFjZS10ZWxlc2NvcGUtaXMtZ2l2aW5nLWh1bWFuaXR5LXdoYXQtd2UtbmVlZC1yaWdodC1ub3cv0gEA?oc=5" target="_blank">The James Webb Space Telescope is giving humanity what we need right now</a>&nbsp;&nbsp;<font color="#6f6f6f">The Boston Globe</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vd3d3LnRoZXJlcHVibGljLmNvbS8yMDIyLzA3LzI3L25hc2FzLXdlYmItaW1hZ2VzLXByb3ZpZGUtYXN0b25pc2htZW50L9IBAA?oc=5" target="_blank">NASA’s Webb images provide astonishment</a>&nbsp;&nbsp;<font color="#6f6f6f">The Republic</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2lmdDU3U0JSRWc0V050U19OOE5TZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + Nature.com + + + First mission to return samples from another planet set to land on Earth in 2033 - CNN + https://news.google.com/__i/rss/rd/articles/CBMiS2h0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy93b3JsZC9tYXJzLXNhbXBsZS1yZXR1cm4tMjAzMy1zY24vaW5kZXguaHRtbNIBT2h0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvd29ybGQvbWFycy1zYW1wbGUtcmV0dXJuLTIwMzMtc2NuL2luZGV4Lmh0bWw?oc=5 + 1506851311 + Wed, 27 Jul 2022 20:40:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiS2h0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy93b3JsZC9tYXJzLXNhbXBsZS1yZXR1cm4tMjAzMy1zY24vaW5kZXguaHRtbNIBT2h0dHBzOi8vYW1wLmNubi5jb20vY25uLzIwMjIvMDcvMjcvd29ybGQvbWFycy1zYW1wbGUtcmV0dXJuLTIwMzMtc2NuL2luZGV4Lmh0bWw?oc=5" target="_blank">First mission to return samples from another planet set to land on Earth in 2033</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiY2h0dHBzOi8vd3d3LmpwbC5uYXNhLmdvdi9uZXdzL25hc2Etd2lsbC1pbnNwaXJlLXdvcmxkLXdoZW4taXQtcmV0dXJucy1tYXJzLXNhbXBsZXMtdG8tZWFydGgtaW4tMjAzM9IBAA?oc=5" target="_blank">NASA Will Inspire World When It Returns Mars Samples to Earth in 2033</a>&nbsp;&nbsp;<font color="#6f6f6f">NASA Jet Propulsion Laboratory</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiXmh0dHBzOi8vbmV3cy5hYnMtY2JuLmNvbS9zcG90bGlnaHQvMDcvMjgvMjIvbmFzYS1kZXRhaWxzLXBsYW5zLXRvLWJyaW5nLWJhY2stbWFycy1yb2NrLXNhbXBsZXPSAWJodHRwczovL25ld3MuYWJzLWNibi5jb20vYW1wL3Nwb3RsaWdodC8wNy8yOC8yMi9uYXNhLWRldGFpbHMtcGxhbnMtdG8tYnJpbmctYmFjay1tYXJzLXJvY2stc2FtcGxlcw?oc=5" target="_blank">NASA details plans to bring back Mars rock samples</a>&nbsp;&nbsp;<font color="#6f6f6f">ABS-CBN News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiemh0dHBzOi8vd3d3LjluZXdzLmNvbS5hdS93b3JsZC9uYXNhLW1hcnMtbWlzc2lvbi1ob3ctc2FtcGxlcy13aWxsLWJlLWJyb3VnaHQtdG8tZWFydGgvNWRiOTliYWUtZjAwMS00YWIzLWI4YzgtZmVmMzAyOTZhNzVh0gEA?oc=5" target="_blank">NASA reveals when first ever Mars samples will return to Earth</a>&nbsp;&nbsp;<font color="#6f6f6f">9News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTmh0dHBzOi8vbWFycy5uYXNhLmdvdi9yZXNvdXJjZXMvMjY4OTUvbWFycy1zYW1wbGUtcmV0dXJuLWNvbmNlcHQtaWxsdXN0cmF0aW9uL9IBAA?oc=5" target="_blank">Mars Sample Return Concept Illustration – NASA Mars Exploration</a>&nbsp;&nbsp;<font color="#6f6f6f">NASA Mars Exploration</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2p2ODhMT0JSRmRSelV2MnYyRGRDZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + CNN + + + CDC warns of deadly bacteria found in Mississippi soil after two residents sickened - CBS News + https://news.google.com/__i/rss/rd/articles/CBMiiwFodHRwczovL3d3dy5jYnNuZXdzLmNvbS9uZXdzL2NkYy13YXJucy1vZi1kZWFkbHktYmFjdGVyaWEtYnVya2hvbGRlcmlhLXBzZXVkb21hbGxlaS1mb3VuZC1pbi1taXNzaXNzaXBwaS1zb2lsLWFmdGVyLXR3by1yZXNpZGVudHMtc2lja2VuZWQv0gGPAWh0dHBzOi8vd3d3LmNic25ld3MuY29tL2FtcC9uZXdzL2NkYy13YXJucy1vZi1kZWFkbHktYmFjdGVyaWEtYnVya2hvbGRlcmlhLXBzZXVkb21hbGxlaS1mb3VuZC1pbi1taXNzaXNzaXBwaS1zb2lsLWFmdGVyLXR3by1yZXNpZGVudHMtc2lja2VuZWQv?oc=5 + 1516088156 + Wed, 27 Jul 2022 23:00:41 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiiwFodHRwczovL3d3dy5jYnNuZXdzLmNvbS9uZXdzL2NkYy13YXJucy1vZi1kZWFkbHktYmFjdGVyaWEtYnVya2hvbGRlcmlhLXBzZXVkb21hbGxlaS1mb3VuZC1pbi1taXNzaXNzaXBwaS1zb2lsLWFmdGVyLXR3by1yZXNpZGVudHMtc2lja2VuZWQv0gGPAWh0dHBzOi8vd3d3LmNic25ld3MuY29tL2FtcC9uZXdzL2NkYy13YXJucy1vZi1kZWFkbHktYmFjdGVyaWEtYnVya2hvbGRlcmlhLXBzZXVkb21hbGxlaS1mb3VuZC1pbi1taXNzaXNzaXBwaS1zb2lsLWFmdGVyLXR3by1yZXNpZGVudHMtc2lja2VuZWQv?oc=5" target="_blank">CDC warns of deadly bacteria found in Mississippi soil after two residents sickened</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiQmh0dHBzOi8vbmV3cy55YWhvby5jb20vY2RjLWZpcnN0LXRpbWUtc2FtcGxlcy10YWtlbi0yMDMyMzI5MjMuaHRtbNIBSmh0dHBzOi8vbmV3cy55YWhvby5jb20vYW1waHRtbC9jZGMtZmlyc3QtdGltZS1zYW1wbGVzLXRha2VuLTIwMzIzMjkyMy5odG1s?oc=5" target="_blank">CDC, for first time from samples taken in U.S., discovers bacteria that causes rare serious disease</a>&nbsp;&nbsp;<font color="#6f6f6f">Yahoo News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvaGVhbHRoL2RlYWRseS1iYWN0ZXJpYS11cy1zb2lsLXdhdGVyLmh0bWzSAQA?oc=5" target="_blank">Potentially Deadly Bacteria Detected in U.S. Soil for First Time</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiV2h0dHBzOi8vd3d3LmFvbC5jb20vbmV3cy9iYWN0ZXJpYS1jYXVzZXMtcmFyZS10cm9waWNhbC1kaXNlYXNlLTE5NDU1Mjg3Ny0yMDA0MzQ1NDQuaHRtbNIBWmh0dHBzOi8vd3d3LmFvbC5jb20vYW1waHRtbC9iYWN0ZXJpYS1jYXVzZXMtcmFyZS10cm9waWNhbC1kaXNlYXNlLTE5NDU1Mjg3Ny0yMDA0MzQ1NDQuaHRtbA?oc=5" target="_blank">Bacteria that causes rare tropical disease found in US soil</a>&nbsp;&nbsp;<font color="#6f6f6f">AOL</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pjMXZiU0JSSHNUc2lSVGNacEJTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + CBS News + + + Supplemental Vitamin D and Incident Fractures in Midlife and Older Adults | NEJM - nejm.org + https://news.google.com/__i/rss/rd/articles/CBMiM2h0dHBzOi8vd3d3Lm5lam0ub3JnL2RvaS9mdWxsLzEwLjEwNTYvTkVKTW9hMjIwMjEwNtIBAA?oc=5 + CBMiM2h0dHBzOi8vd3d3Lm5lam0ub3JnL2RvaS9mdWxsLzEwLjEwNTYvTkVKTW9hMjIwMjEwNtIBAA + Wed, 27 Jul 2022 21:01:41 GMT + <a href="https://news.google.com/__i/rss/rd/articles/CBMiM2h0dHBzOi8vd3d3Lm5lam0ub3JnL2RvaS9mdWxsLzEwLjEwNTYvTkVKTW9hMjIwMjEwNtIBAA?oc=5" target="_blank">Supplemental Vitamin D and Incident Fractures in Midlife and Older Adults | NEJM</a>&nbsp;&nbsp;<font color="#6f6f6f">nejm.org</font><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2kyMV9uU0JSRjBUd1l5TC13cHVTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong> + nejm.org + + + U.S. to Distribute 800,000 Doses of Monkeypox Vaccine - The New York Times + https://news.google.com/__i/rss/rd/articles/CBMiRmh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvaGVhbHRoL21vbmtleXBveC12YWNjaW5lLWRvc2VzLmh0bWzSAQA?oc=5 + 1515487028 + Wed, 27 Jul 2022 22:31:50 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiRmh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjIvMDcvMjcvaGVhbHRoL21vbmtleXBveC12YWNjaW5lLWRvc2VzLmh0bWzSAQA?oc=5" target="_blank">U.S. to Distribute 800,000 Doses of Monkeypox Vaccine</a>&nbsp;&nbsp;<font color="#6f6f6f">The New York Times</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9SXJJcmZkX0pvMjDSAQA?oc=5" target="_blank">Nearly 800000 more monkeypox vaccine doses to be available in U.S.</a>&nbsp;&nbsp;<font color="#6f6f6f">CBS News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiR2h0dHBzOi8vd3d3LmZveG5ld3MuY29tL2hlYWx0aC9ueWMtYXNrcy13aG8tcmVuYW1lLW1vbmtleXBveC1kdWUtc3RpZ21h0gEA?oc=5" target="_blank">NYC asks WHO to rename monkeypox due to stigma</a>&nbsp;&nbsp;<font color="#6f6f6f">Fox News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiYmh0dHBzOi8vd3d3LnRpbWVvdXQuY29tL25ld3lvcmsvbmV3cy9tb25rZXlwb3gtaW4tbmV3LXlvcmstY2l0eS1oZXJlcy13aGF0LXlvdS1uZWVkLXRvLWtub3ctMDcyNzIy0gEA?oc=5" target="_blank">Monkeypox in New York City: Here's what you need to know</a>&nbsp;&nbsp;<font color="#6f6f6f">Time Out</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9VC1rU0RqNlExeU3SAQA?oc=5" target="_blank">Monkeypox U S leads world in cases and vaccine distribution stumbles</a>&nbsp;&nbsp;<font color="#6f6f6f">CGTN America</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2kwX3RIU0JSRXlIdzdlNzl2cjdTZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + The New York Times + + + WHO chief advises men who have sex with men to reduce partners to limit exposure to monkeypox - CNN + https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9oZWFsdGgvd2hvLW1vbmtleXBveC1tc20tc2V4LXBhcnRuZXJzL2luZGV4Lmh0bWzSAVNodHRwczovL2FtcC5jbm4uY29tL2Nubi8yMDIyLzA3LzI3L2hlYWx0aC93aG8tbW9ua2V5cG94LW1zbS1zZXgtcGFydG5lcnMvaW5kZXguaHRtbA?oc=5 + 1507101674 + Thu, 28 Jul 2022 00:43:00 GMT + <ol><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiT2h0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9oZWFsdGgvd2hvLW1vbmtleXBveC1tc20tc2V4LXBhcnRuZXJzL2luZGV4Lmh0bWzSAVNodHRwczovL2FtcC5jbm4uY29tL2Nubi8yMDIyLzA3LzI3L2hlYWx0aC93aG8tbW9ua2V5cG94LW1zbS1zZXgtcGFydG5lcnMvaW5kZXguaHRtbA?oc=5" target="_blank">WHO chief advises men who have sex with men to reduce partners to limit exposure to monkeypox</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiTWh0dHBzOi8vd3d3LmJ1enpmZWVkbmV3cy5jb20vYXJ0aWNsZS9kYXZpZG1hY2svbWVuLXNleC1wYXJ0bmVycy1tb25rZXlwb3gtd2hv0gEA?oc=5" target="_blank">Men Who Have Sex With Men Should Reduce Their Partners For Now To Avoid Monkeypox, The WHO Has Advised</a>&nbsp;&nbsp;<font color="#6f6f6f">BuzzFeed News</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMidWh0dHBzOi8vd3d3LmNuYmMuY29tLzIwMjIvMDcvMjcvbW9ua2V5cG94LXdoby1yZWNvbW1lbmRzLWdheS1iaXNleHVhbC1tZW4tbGltaXQtc2V4dWFsLXBhcnRuZXJzLXRvLXJlZHVjZS1zcHJlYWQuaHRtbNIBAA?oc=5" target="_blank">WHO recommends gay and bisexual men limit sexual partners to reduce the spread of monkeypox</a>&nbsp;&nbsp;<font color="#6f6f6f">CNBC</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiVmh0dHBzOi8vd3d3LmNubi5jb20vMjAyMi8wNy8yNy9oZWFsdGgvbW9ua2V5cG94LXZhY2NpbmUtaGVhbHRoLXdlbi13ZWxsbmVzcy9pbmRleC5odG1s0gFaaHR0cHM6Ly9hbXAuY25uLmNvbS9jbm4vMjAyMi8wNy8yNy9oZWFsdGgvbW9ua2V5cG94LXZhY2NpbmUtaGVhbHRoLXdlbi13ZWxsbmVzcy9pbmRleC5odG1s?oc=5" target="_blank">Now should I worry about monkeypox? Our medical analyst explains</a>&nbsp;&nbsp;<font color="#6f6f6f">CNN</font></li><li><a href="https://news.google.com/__i/rss/rd/articles/CBMiaWh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vbmV3cy8yMDIyLzcvMjcvYXMtbW9ua2V5cG94LXN1cmdlcy13aG8tdXJnZXMtcmVkdWNpbmctbnVtYmVyLW9mLXNleHVhbC1wYXJ0bmVyc9IBbWh0dHBzOi8vd3d3LmFsamF6ZWVyYS5jb20vYW1wL25ld3MvMjAyMi83LzI3L2FzLW1vbmtleXBveC1zdXJnZXMtd2hvLXVyZ2VzLXJlZHVjaW5nLW51bWJlci1vZi1zZXh1YWwtcGFydG5lcnM?oc=5" target="_blank">As monkeypox surges, WHO urges reducing number of sexual partners</a>&nbsp;&nbsp;<font color="#6f6f6f">Al Jazeera English</font></li><li><strong><a href="https://news.google.com/stories/CAAqNggKIjBDQklTSGpvSmMzUnZjbmt0TXpZd1NoRUtEd2pxbDlMT0JSSFpnWU5uazVTOEppZ0FQAQ?oc=5" target="_blank">View Full Coverage on Google News</a></strong></li></ol> + CNN + + + diff --git a/test-data/rss-feed-standard.xml b/test-data/rss-feed-standard.xml new file mode 100644 index 0000000..795099b --- /dev/null +++ b/test-data/rss-feed-standard.xml @@ -0,0 +1,19 @@ + + + + RSS Title + This is an example of an RSS feed + http://www.example.com/main.html + 2020 Example.com All rights reserved + Mon, 6 September 2010 00:01:00 +0000 + Sun, 6 September 2009 16:20:00 +0000 + 1800 + + Example entry + Here is some text containing an interesting description. + http://www.example.com/blog/post/1 + 7bd204c6-1655-4c27-aeee-53f933c5395f + Sun, 6 September 2009 16:20:00 +0000 + + + diff --git a/test-data/rss-with-single-item.xml b/test-data/rss-with-single-item.xml deleted file mode 100644 index e60ead3..0000000 --- a/test-data/rss-with-single-item.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - NFE/5.0 - Top stories - Google News - https://news.google.com/?hl=en-US&gl=US&ceid=US:en - en-US - news-webmaster@google.com - 2021 Google Inc. - Sat, 20 Nov 2021 10:44:20 GMT - Google News - - Biden gets first physical as president, power transferred to VP Harris - ABC News - https://news.google.com/__i/rss/rd/articles/CBMiZmh0dHBzOi8vYWJjbmV3cy5nby5jb20vUG9saXRpY3MvYmlkZW4tcGh5c2ljYWwtcHJlc2lkZW50LXBvd2VyLXRyYW5zZmVycmVkLXZwLWhhcnJpcy9zdG9yeT9pZD04MTI1OTAyMNIBamh0dHBzOi8vYWJjbmV3cy5nby5jb20vYW1wL1BvbGl0aWNzL2JpZGVuLXBoeXNpY2FsLXByZXNpZGVudC1wb3dlci10cmFuc2ZlcnJlZC12cC1oYXJyaXMvc3Rvcnk_aWQ9ODEyNTkwMjA?oc=5 - 1181825440 - Fri, 19 Nov 2021 23:26:15 GMT - Something new here - ABC News - - - diff --git a/test-data/rss.xml b/test-data/rss.xml deleted file mode 100755 index 7faeb1b..0000000 --- a/test-data/rss.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - NFE/5.0 - Top stories - Google News - https://news.google.com/?hl=en-US&gl=US&ceid=US:en - en-US - news-webmaster@google.com - 2021 Google Inc. - Sat, 20 Nov 2021 10:44:20 GMT - Google News - - Kyle Rittenhouse Breaks Silence After Not Guilty Verdict - NBC Chicago - https://news.google.com/__i/rss/rd/articles/CBMiZ2h0dHBzOi8vd3d3Lm5iY2NoaWNhZ28uY29tL25ld3MvbG9jYWwva3lsZS1yaXR0ZW5ob3VzZS1icmVha3Mtc2lsZW5jZS1hZnRlci1ub3QtZ3VpbHR5LXZlcmRpY3QvMjY4OTkzNi_SAWtodHRwczovL3d3dy5uYmNjaGljYWdvLmNvbS9uZXdzL2xvY2FsL2t5bGUtcml0dGVuaG91c2UtYnJlYWtzLXNpbGVuY2UtYWZ0ZXItbm90LWd1aWx0eS12ZXJkaWN0LzI2ODk5MzYvP2FtcA?oc=5 - 1133952206 - Sat, 20 Nov 2021 07:25:12 GMT - Something new here - NBC Chicago - - - Biden gets first physical as president, power transferred to VP Harris - ABC News - https://news.google.com/__i/rss/rd/articles/CBMiZmh0dHBzOi8vYWJjbmV3cy5nby5jb20vUG9saXRpY3MvYmlkZW4tcGh5c2ljYWwtcHJlc2lkZW50LXBvd2VyLXRyYW5zZmVycmVkLXZwLWhhcnJpcy9zdG9yeT9pZD04MTI1OTAyMNIBamh0dHBzOi8vYWJjbmV3cy5nby5jb20vYW1wL1BvbGl0aWNzL2JpZGVuLXBoeXNpY2FsLXByZXNpZGVudC1wb3dlci10cmFuc2ZlcnJlZC12cC1oYXJyaXMvc3Rvcnk_aWQ9ODEyNTkwMjA?oc=5 - 1181825440 - Fri, 19 Nov 2021 23:26:15 GMT - Something new here - ABC News - - - From fa9d5bcd26e7bd3eacb5ab3354226b4b93853f95 Mon Sep 17 00:00:00 2001 From: Dong Nguyen Date: Thu, 28 Jul 2022 16:39:05 +0700 Subject: [PATCH 2/3] Run lint before test --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 463b69e..34e78ae 100755 --- a/package.json +++ b/package.json @@ -16,10 +16,11 @@ }, "scripts": { "lint": "standard .", + "pretest": "npm run lint", "test": "NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --verbose --coverage=true --unhandled-rejections=strict --detectOpenHandles", "build": "node build src/main.js", - "eval": "DEBUG=*:* node eval", - "eval:cjs": "DEBUG=*:* node cjs-eval", + "eval": "node eval", + "eval:cjs": "node cjs-eval", "reset": "node reset" }, "dependencies": { From ba5bdee4684d27c4279873f3e30ea5d3a8b86be0 Mon Sep 17 00:00:00 2001 From: Dong Nguyen Date: Thu, 28 Jul 2022 16:42:34 +0700 Subject: [PATCH 3/3] Fix standard format --- dist/cjs/feed-reader.js | 176 ++++++++++++++++++++++++++++++------- src/utils/parseJsonFeed.js | 4 +- 2 files changed, 145 insertions(+), 35 deletions(-) diff --git a/dist/cjs/feed-reader.js b/dist/cjs/feed-reader.js index 354f02d..aab60de 100644 --- a/dist/cjs/feed-reader.js +++ b/dist/cjs/feed-reader.js @@ -1,4 +1,4 @@ -// feed-reader@6.0.0rc3, by @ndaidong - built with esbuild at 2022-07-28T09:33:03.350Z - published under MIT license +// feed-reader@6.0.0rc3, by @ndaidong - built with esbuild at 2022-07-28T09:42:29.894Z - published under MIT license var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; @@ -20,7 +20,10 @@ var __copyProps = (to, from, except, desc) => { } return to; }; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/bind.js @@ -494,7 +497,13 @@ var require_settle = __commonJS({ if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response); } else { - reject(new AxiosError("Request failed with status code " + response.status, [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], response.config, response.request, response)); + reject(new AxiosError( + "Request failed with status code " + response.status, + [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], + response.config, + response.request, + response + )); } }; } @@ -795,7 +804,12 @@ var require_xhr = __commonJS({ if (config.timeoutErrorMessage) { timeoutErrorMessage = config.timeoutErrorMessage; } - reject(new AxiosError(timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, request)); + reject(new AxiosError( + timeoutErrorMessage, + transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, + config, + request + )); request = null; }; if (utils.isStandardBrowserEnv()) { @@ -870,14 +884,18 @@ var require_ms = __commonJS({ } else if (type === "number" && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } - throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(val)); + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); }; function parse(str) { str = String(str); if (str.length > 100) { return; } - var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str); + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); if (!match) { return; } @@ -1419,8 +1437,11 @@ var require_node = __commonJS({ exports.save = save; exports.load = load; exports.useColors = useColors; - exports.destroy = util.deprecate(() => { - }, "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + exports.destroy = util.deprecate( + () => { + }, + "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`." + ); exports.colors = [6, 2, 3, 4, 5, 1]; try { const supportsColor = require_supports_color(); @@ -1627,10 +1648,22 @@ var require_follow_redirects = __commonJS({ this._redirectable.emit(event, arg1, arg2, arg3); }; }); - var RedirectionError = createErrorType("ERR_FR_REDIRECTION_FAILURE", "Redirected request failed"); - var TooManyRedirectsError = createErrorType("ERR_FR_TOO_MANY_REDIRECTS", "Maximum number of redirects exceeded"); - var MaxBodyLengthExceededError = createErrorType("ERR_FR_MAX_BODY_LENGTH_EXCEEDED", "Request body larger than maxBodyLength limit"); - var WriteAfterEndError = createErrorType("ERR_STREAM_WRITE_AFTER_END", "write after end"); + var RedirectionError = createErrorType( + "ERR_FR_REDIRECTION_FAILURE", + "Redirected request failed" + ); + var TooManyRedirectsError = createErrorType( + "ERR_FR_TOO_MANY_REDIRECTS", + "Maximum number of redirects exceeded" + ); + var MaxBodyLengthExceededError = createErrorType( + "ERR_FR_MAX_BODY_LENGTH_EXCEEDED", + "Request body larger than maxBodyLength limit" + ); + var WriteAfterEndError = createErrorType( + "ERR_STREAM_WRITE_AFTER_END", + "write after end" + ); function RedirectableRequest(options, responseCallback) { Writable.call(this); this._sanitizeOptions(options); @@ -2103,10 +2136,18 @@ var require_http = __commonJS({ } else if (utils.isString(data)) { data = Buffer.from(data, "utf-8"); } else { - return reject(new AxiosError("Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream", AxiosError.ERR_BAD_REQUEST, config)); + return reject(new AxiosError( + "Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream", + AxiosError.ERR_BAD_REQUEST, + config + )); } if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) { - return reject(new AxiosError("Request body larger than maxBodyLength limit", AxiosError.ERR_BAD_REQUEST, config)); + return reject(new AxiosError( + "Request body larger than maxBodyLength limit", + AxiosError.ERR_BAD_REQUEST, + config + )); } if (!headerNames["content-length"]) { headers["Content-Length"] = data.length; @@ -2122,7 +2163,11 @@ var require_http = __commonJS({ var parsed = url.parse(fullPath); var protocol = parsed.protocol || supportedProtocols[0]; if (supportedProtocols.indexOf(protocol) === -1) { - return reject(new AxiosError("Unsupported protocol " + protocol, AxiosError.ERR_BAD_REQUEST, config)); + return reject(new AxiosError( + "Unsupported protocol " + protocol, + AxiosError.ERR_BAD_REQUEST, + config + )); } if (!auth && parsed.auth) { var urlAuth = parsed.auth.split(":"); @@ -2258,7 +2303,12 @@ var require_http = __commonJS({ if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) { rejected = true; stream.destroy(); - reject(new AxiosError("maxContentLength size of " + config.maxContentLength + " exceeded", AxiosError.ERR_BAD_RESPONSE, config, lastRequest)); + reject(new AxiosError( + "maxContentLength size of " + config.maxContentLength + " exceeded", + AxiosError.ERR_BAD_RESPONSE, + config, + lastRequest + )); } }); stream.on("aborted", function handlerStreamAborted() { @@ -2266,7 +2316,12 @@ var require_http = __commonJS({ return; } stream.destroy(); - reject(new AxiosError("maxContentLength size of " + config.maxContentLength + " exceeded", AxiosError.ERR_BAD_RESPONSE, config, lastRequest)); + reject(new AxiosError( + "maxContentLength size of " + config.maxContentLength + " exceeded", + AxiosError.ERR_BAD_RESPONSE, + config, + lastRequest + )); }); stream.on("error", function handleStreamError(err) { if (req.aborted) @@ -2299,13 +2354,23 @@ var require_http = __commonJS({ if (config.timeout) { var timeout = parseInt(config.timeout, 10); if (isNaN(timeout)) { - reject(new AxiosError("error trying to parse `config.timeout` to int", AxiosError.ERR_BAD_OPTION_VALUE, config, req)); + reject(new AxiosError( + "error trying to parse `config.timeout` to int", + AxiosError.ERR_BAD_OPTION_VALUE, + config, + req + )); return; } req.setTimeout(timeout, function handleRequestTimeout() { req.abort(); var transitional = config.transitional || transitionalDefaults; - reject(new AxiosError("timeout of " + timeout + "ms exceeded", transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, req)); + reject(new AxiosError( + "timeout of " + timeout + "ms exceeded", + transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, + config, + req + )); }); } if (config.cancelToken || config.signal) { @@ -11917,21 +11982,43 @@ var require_dispatchRequest = __commonJS({ module2.exports = function dispatchRequest(config) { throwIfCancellationRequested(config); config.headers = config.headers || {}; - config.data = transformData.call(config, config.data, config.headers, config.transformRequest); - config.headers = utils.merge(config.headers.common || {}, config.headers[config.method] || {}, config.headers); - utils.forEach(["delete", "get", "head", "post", "put", "patch", "common"], function cleanHeaderConfig(method) { - delete config.headers[method]; - }); + config.data = transformData.call( + config, + config.data, + config.headers, + config.transformRequest + ); + config.headers = utils.merge( + config.headers.common || {}, + config.headers[config.method] || {}, + config.headers + ); + utils.forEach( + ["delete", "get", "head", "post", "put", "patch", "common"], + function cleanHeaderConfig(method) { + delete config.headers[method]; + } + ); var adapter = config.adapter || defaults.adapter; return adapter(config).then(function onAdapterResolution(response) { throwIfCancellationRequested(config); - response.data = transformData.call(config, response.data, response.headers, config.transformResponse); + response.data = transformData.call( + config, + response.data, + response.headers, + config.transformResponse + ); return response; }, function onAdapterRejection(reason) { if (!isCancel(reason)) { throwIfCancellationRequested(config); if (reason && reason.response) { - reason.response.data = transformData.call(config, reason.response.data, reason.response.headers, config.transformResponse); + reason.response.data = transformData.call( + config, + reason.response.data, + reason.response.headers, + config.transformResponse + ); } } return Promise.reject(reason); @@ -12042,11 +12129,19 @@ var require_validator = __commonJS({ } return function(value, opt, opts) { if (validator === false) { - throw new AxiosError(formatMessage(opt, " has been removed" + (version ? " in " + version : "")), AxiosError.ERR_DEPRECATED); + throw new AxiosError( + formatMessage(opt, " has been removed" + (version ? " in " + version : "")), + AxiosError.ERR_DEPRECATED + ); } if (version && !deprecatedWarnings[opt]) { deprecatedWarnings[opt] = true; - console.warn(formatMessage(opt, " has been deprecated since v" + version + " and will be removed in the near future")); + console.warn( + formatMessage( + opt, + " has been deprecated since v" + version + " and will be removed in the near future" + ) + ); } return validator ? validator(value, opt, opts) : true; }; @@ -12707,7 +12802,11 @@ var require_validator2 = __commonJS({ const otg = tags.pop(); if (tagName !== otg.tagName) { let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos); - return getErrorObject("InvalidTag", "Expected closing tag '" + otg.tagName + "' (opened in line " + openPos.line + ", col " + openPos.col + ") instead of closing tag '" + tagName + "'.", getLineNumberForPosition(xmlData, tagStartPos)); + return getErrorObject( + "InvalidTag", + "Expected closing tag '" + otg.tagName + "' (opened in line " + openPos.line + ", col " + openPos.col + ") instead of closing tag '" + tagName + "'.", + getLineNumberForPosition(xmlData, tagStartPos) + ); } if (tags.length == 0) { reachedRoot = true; @@ -13286,7 +13385,11 @@ var require_OrderedObjParser = __commonJS({ } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) { attrs[aName] = newVal; } else { - attrs[aName] = parseValue(oldVal, this.options.parseAttributeValue, this.options.numberParseOptions); + attrs[aName] = parseValue( + oldVal, + this.options.parseAttributeValue, + this.options.numberParseOptions + ); } } else if (this.options.allowBooleanAttributes) { attrs[aName] = true; @@ -13475,7 +13578,14 @@ var require_OrderedObjParser = __commonJS({ if (textData) { if (isLeafNode === void 0) isLeafNode = Object.keys(currentNode.child).length === 0; - textData = this.parseTextData(textData, currentNode.tagname, jPath, false, currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false, isLeafNode); + textData = this.parseTextData( + textData, + currentNode.tagname, + jPath, + false, + currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false, + isLeafNode + ); if (textData !== void 0 && textData !== "") currentNode.add(this.options.textNodeName, textData); textData = ""; @@ -14525,7 +14635,7 @@ var transform = (item) => { var parseJson = (data) => { const { title = "", - home_page_url = "", + home_page_url: homepageUrl = "", description = "", language = "", items: item = [] @@ -14533,7 +14643,7 @@ var parseJson = (data) => { const items = (0, import_bellajs5.isArray)(item) ? item : [item]; return { title, - link: home_page_url, + link: homepageUrl, description, language, published: "", diff --git a/src/utils/parseJsonFeed.js b/src/utils/parseJsonFeed.js index 20b68b3..688ed77 100644 --- a/src/utils/parseJsonFeed.js +++ b/src/utils/parseJsonFeed.js @@ -42,7 +42,7 @@ const transform = (item) => { const parseJson = (data) => { const { title = '', - home_page_url = '', + home_page_url: homepageUrl = '', description = '', language = '', items: item = [] @@ -52,7 +52,7 @@ const parseJson = (data) => { return { title, - link: home_page_url, + link: homepageUrl, description, language, published: '',