diff --git a/README.md b/README.md
index 109804d85..b1a1c24bd 100644
--- a/README.md
+++ b/README.md
@@ -46,6 +46,7 @@ If you need something that is not already part of Bazarr, feel free to create a
* Assrt
* BetaSeries
* BSplayer
+* Embedded Subtitles
* GreekSubtitles
* Hosszupuska
* LegendasDivx
diff --git a/bazarr.py b/bazarr.py
index 5b6d077ba..a61540149 100644
--- a/bazarr.py
+++ b/bazarr.py
@@ -20,8 +20,8 @@ def check_python_version():
print("Python " + minimum_py3_str + " or greater required. "
"Current version is " + platform.python_version() + ". Please upgrade Python.")
sys.exit(1)
- elif int(python_version[0]) == 3 and int(python_version[1]) == 9:
- print("Python 3.9.x is unsupported. Current version is " + platform.python_version() +
+ elif int(python_version[0]) == 3 and int(python_version[1]) > 10:
+ print("Python version greater than 3.10.x is unsupported. Current version is " + platform.python_version() +
". Keep in mind that even if it works, you're on your own.")
elif (int(python_version[0]) == minimum_py3_tuple[0] and int(python_version[1]) < minimum_py3_tuple[1]) or \
(int(python_version[0]) != minimum_py3_tuple[0]):
diff --git a/bazarr/api.py b/bazarr/api.py
deleted file mode 100644
index 97ea20c4a..000000000
--- a/bazarr/api.py
+++ /dev/null
@@ -1,2192 +0,0 @@
-# coding=utf-8
-
-import sys
-import os
-import ast
-from datetime import timedelta
-from dateutil import rrule
-import pretty
-import time
-import operator
-from operator import itemgetter
-from functools import reduce
-import platform
-import re
-import json
-import hashlib
-import apprise
-import gc
-from peewee import fn, Value
-import requests
-from bs4 import BeautifulSoup as bso
-
-from get_args import args
-from config import settings, base_url, save_settings, get_settings
-from logger import empty_log
-from init import startTime
-
-from init import *
-import logging
-from database import get_exclusion_clause, get_profiles_list, get_desired_languages, get_profile_id_name, \
- get_audio_profile_languages, update_profile_id_list, convert_list_to_clause, TableEpisodes, TableShows, \
- TableMovies, TableSettingsLanguages, TableSettingsNotifier, TableLanguagesProfiles, TableHistory, \
- TableHistoryMovie, TableBlacklist, TableBlacklistMovie
-from helper import path_mappings
-from get_languages import language_from_alpha2, language_from_alpha3, alpha2_from_alpha3, alpha3_from_alpha2
-from get_subtitle import download_subtitle, series_download_subtitles, manual_search, manual_download_subtitle, \
- manual_upload_subtitle, wanted_search_missing_subtitles_series, wanted_search_missing_subtitles_movies, \
- episode_download_subtitles, movies_download_subtitles
-from notifier import send_notifications, send_notifications_movie
-from list_subtitles import store_subtitles, store_subtitles_movie, series_scan_subtitles, movies_scan_subtitles, \
- list_missing_subtitles, list_missing_subtitles_movies
-from utils import history_log, history_log_movie, blacklist_log, blacklist_delete, blacklist_delete_all, \
- blacklist_log_movie, blacklist_delete_movie, blacklist_delete_all_movie, get_sonarr_info, get_radarr_info, \
- delete_subtitles, subtitles_apply_mods, translate_subtitles_file, check_credentials, get_health_issues
-from get_providers import get_providers, get_providers_auth, list_throttled_providers, reset_throttled_providers, \
- get_throttled_providers, set_throttled_providers
-from event_handler import event_stream
-from scheduler import scheduler
-from subsyncer import subsync
-from filesystem import browse_bazarr_filesystem, browse_sonarr_filesystem, browse_radarr_filesystem
-
-from subliminal_patch.core import SUBTITLE_EXTENSIONS, guessit
-
-from flask import Flask, jsonify, request, Response, Blueprint, url_for, make_response, session
-
-from flask_restful import Resource, Api, abort
-from functools import wraps
-
-api_bp = Blueprint('api', __name__, url_prefix=base_url.rstrip('/') + '/api')
-api = Api(api_bp)
-
-None_Keys = ['null', 'undefined', '', None]
-
-False_Keys = ['False', 'false', '0']
-
-
-def authenticate(actual_method):
- @wraps(actual_method)
- def wrapper(*args, **kwargs):
- apikey_settings = settings.auth.apikey
- apikey_get = request.args.get('apikey')
- apikey_post = request.form.get('apikey')
- apikey_header = None
- if 'X-API-KEY' in request.headers:
- apikey_header = request.headers['X-API-KEY']
-
- if apikey_settings in [apikey_get, apikey_post, apikey_header]:
- return actual_method(*args, **kwargs)
-
- return abort(401)
-
- return wrapper
-
-
-def postprocess(item):
- # Remove ffprobe_cache
- if 'ffprobe_cache' in item:
- del (item['ffprobe_cache'])
-
- # Parse tags
- if 'tags' in item:
- if item['tags'] is None:
- item['tags'] = []
- else:
- item['tags'] = ast.literal_eval(item['tags'])
-
- if 'monitored' in item:
- if item['monitored'] is None:
- item['monitored'] = False
- else:
- item['monitored'] = item['monitored'] == 'True'
-
- if 'hearing_impaired' in item and item['hearing_impaired'] is not None:
- if item['hearing_impaired'] is None:
- item['hearing_impaired'] = False
- else:
- item['hearing_impaired'] = item['hearing_impaired'] == 'True'
-
- if 'language' in item:
- if item['language'] == 'None':
- item['language'] = None
- elif item['language'] is not None:
- splitted_language = item['language'].split(':')
- item['language'] = {"name": language_from_alpha2(splitted_language[0]),
- "code2": splitted_language[0],
- "code3": alpha3_from_alpha2(splitted_language[0]),
- "forced": True if item['language'].endswith(':forced') else False,
- "hi": True if item['language'].endswith(':hi') else False}
-
-
-def postprocessSeries(item):
- postprocess(item)
- # Parse audio language
- if 'audio_language' in item and item['audio_language'] is not None:
- item['audio_language'] = get_audio_profile_languages(series_id=item['sonarrSeriesId'])
-
- if 'alternateTitles' in item:
- if item['alternateTitles'] is None:
- item['alternativeTitles'] = []
- else:
- item['alternativeTitles'] = ast.literal_eval(item['alternateTitles'])
- del item["alternateTitles"]
-
- # Parse seriesType
- if 'seriesType' in item and item['seriesType'] is not None:
- item['seriesType'] = item['seriesType'].capitalize()
-
- if 'path' in item:
- item['path'] = path_mappings.path_replace(item['path'])
-
- # map poster and fanart to server proxy
- if 'poster' in item:
- poster = item['poster']
- item['poster'] = f"{base_url}/images/series{poster}"
-
- if 'fanart' in item:
- fanart = item['fanart']
- item['fanart'] = f"{base_url}/images/series{fanart}"
-
-
-def postprocessEpisode(item):
- postprocess(item)
- if 'audio_language' in item and item['audio_language'] is not None:
- item['audio_language'] = get_audio_profile_languages(episode_id=item['sonarrEpisodeId'])
-
- if 'subtitles' in item:
- if item['subtitles'] is None:
- raw_subtitles = []
- else:
- raw_subtitles = ast.literal_eval(item['subtitles'])
- subtitles = []
-
- for subs in raw_subtitles:
- subtitle = subs[0].split(':')
- sub = {"name": language_from_alpha2(subtitle[0]),
- "code2": subtitle[0],
- "code3": alpha3_from_alpha2(subtitle[0]),
- "path": path_mappings.path_replace(subs[1]),
- "forced": False,
- "hi": False}
- if len(subtitle) > 1:
- sub["forced"] = True if subtitle[1] == 'forced' else False
- sub["hi"] = True if subtitle[1] == 'hi' else False
-
- subtitles.append(sub)
-
- item.update({"subtitles": subtitles})
-
- # Parse missing subtitles
- if 'missing_subtitles' in item:
- if item['missing_subtitles'] is None:
- item['missing_subtitles'] = []
- else:
- item['missing_subtitles'] = ast.literal_eval(item['missing_subtitles'])
- for i, subs in enumerate(item['missing_subtitles']):
- subtitle = subs.split(':')
- item['missing_subtitles'][i] = {"name": language_from_alpha2(subtitle[0]),
- "code2": subtitle[0],
- "code3": alpha3_from_alpha2(subtitle[0]),
- "forced": False,
- "hi": False}
- if len(subtitle) > 1:
- item['missing_subtitles'][i].update({
- "forced": True if subtitle[1] == 'forced' else False,
- "hi": True if subtitle[1] == 'hi' else False
- })
-
- if 'scene_name' in item:
- item["sceneName"] = item["scene_name"]
- del item["scene_name"]
-
- if 'path' in item and item['path']:
- # Provide mapped path
- item['path'] = path_mappings.path_replace(item['path'])
-
-
-# TODO: Move
-def postprocessMovie(item):
- postprocess(item)
- # Parse audio language
- if 'audio_language' in item and item['audio_language'] is not None:
- item['audio_language'] = get_audio_profile_languages(movie_id=item['radarrId'])
-
- # Parse alternate titles
- if 'alternativeTitles' in item:
- if item['alternativeTitles'] is None:
- item['alternativeTitles'] = []
- else:
- item['alternativeTitles'] = ast.literal_eval(item['alternativeTitles'])
-
- # Parse failed attempts
- if 'failedAttempts' in item:
- if item['failedAttempts']:
- item['failedAttempts'] = ast.literal_eval(item['failedAttempts'])
-
- # Parse subtitles
- if 'subtitles' in item:
- if item['subtitles'] is None:
- item['subtitles'] = []
- else:
- item['subtitles'] = ast.literal_eval(item['subtitles'])
- for i, subs in enumerate(item['subtitles']):
- language = subs[0].split(':')
- item['subtitles'][i] = {"path": path_mappings.path_replace_movie(subs[1]),
- "name": language_from_alpha2(language[0]),
- "code2": language[0],
- "code3": alpha3_from_alpha2(language[0]),
- "forced": False,
- "hi": False}
- if len(language) > 1:
- item['subtitles'][i].update({
- "forced": True if language[1] == 'forced' else False,
- "hi": True if language[1] == 'hi' else False
- })
-
- if settings.general.getboolean('embedded_subs_show_desired'):
- desired_lang_list = get_desired_languages(item['profileId'])
- item['subtitles'] = [x for x in item['subtitles'] if x['code2'] in desired_lang_list or x['path']]
-
- item['subtitles'] = sorted(item['subtitles'], key=itemgetter('name', 'forced'))
-
- # Parse missing subtitles
- if 'missing_subtitles' in item:
- if item['missing_subtitles'] is None:
- item['missing_subtitles'] = []
- else:
- item['missing_subtitles'] = ast.literal_eval(item['missing_subtitles'])
- for i, subs in enumerate(item['missing_subtitles']):
- language = subs.split(':')
- item['missing_subtitles'][i] = {"name": language_from_alpha2(language[0]),
- "code2": language[0],
- "code3": alpha3_from_alpha2(language[0]),
- "forced": False,
- "hi": False}
- if len(language) > 1:
- item['missing_subtitles'][i].update({
- "forced": True if language[1] == 'forced' else False,
- "hi": True if language[1] == 'hi' else False
- })
-
- # Provide mapped path
- if 'path' in item:
- if item['path']:
- item['path'] = path_mappings.path_replace_movie(item['path'])
-
- if 'subtitles_path' in item:
- # Provide mapped subtitles path
- item['subtitles_path'] = path_mappings.path_replace_movie(item['subtitles_path'])
-
- # map poster and fanart to server proxy
- if 'poster' in item:
- poster = item['poster']
- item['poster'] = f"{base_url}/images/movies{poster}"
-
- if 'fanart' in item:
- fanart = item['fanart']
- item['fanart'] = f"{base_url}/images/movies{fanart}"
-
-
-class SystemAccount(Resource):
- def post(self):
- if settings.auth.type != 'form':
- return '', 405
-
- action = request.args.get('action')
- if action == 'login':
- username = request.form.get('username')
- password = request.form.get('password')
- if check_credentials(username, password):
- session['logged_in'] = True
- return '', 204
- elif action == 'logout':
- session.clear()
- gc.collect()
- return '', 204
-
- return '', 401
-
-
-class System(Resource):
- @authenticate
- def post(self):
- from server import webserver
- action = request.args.get('action')
- if action == "shutdown":
- webserver.shutdown()
- elif action == "restart":
- webserver.restart()
- return '', 204
-
-
-class Badges(Resource):
- @authenticate
- def get(self):
- episodes_conditions = [(TableEpisodes.missing_subtitles is not None),
- (TableEpisodes.missing_subtitles != '[]')]
- episodes_conditions += get_exclusion_clause('series')
- missing_episodes = TableEpisodes.select(TableShows.tags,
- TableShows.seriesType,
- TableEpisodes.monitored)\
- .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .where(reduce(operator.and_, episodes_conditions))\
- .count()
-
- movies_conditions = [(TableMovies.missing_subtitles is not None),
- (TableMovies.missing_subtitles != '[]')]
- movies_conditions += get_exclusion_clause('movie')
- missing_movies = TableMovies.select(TableMovies.tags,
- TableMovies.monitored)\
- .where(reduce(operator.and_, movies_conditions))\
- .count()
-
- throttled_providers = len(eval(str(get_throttled_providers())))
-
- health_issues = len(get_health_issues())
-
- result = {
- "episodes": missing_episodes,
- "movies": missing_movies,
- "providers": throttled_providers,
- "status": health_issues
- }
- return jsonify(result)
-
-
-class Languages(Resource):
- @authenticate
- def get(self):
- history = request.args.get('history')
- if history and history not in False_Keys:
- languages = list(TableHistory.select(TableHistory.language)
- .where(TableHistory.language != None)
- .dicts())
- languages += list(TableHistoryMovie.select(TableHistoryMovie.language)
- .where(TableHistoryMovie.language != None)
- .dicts())
- languages_list = list(set([l['language'].split(':')[0] for l in languages]))
- languages_dicts = []
- for language in languages_list:
- code2 = None
- if len(language) == 2:
- code2 = language
- elif len(language) == 3:
- code2 = alpha2_from_alpha3(language)
- else:
- continue
-
- if not any(x['code2'] == code2 for x in languages_dicts):
- try:
- languages_dicts.append({
- 'code2': code2,
- 'name': language_from_alpha2(code2),
- # Compatibility: Use false temporarily
- 'enabled': False
- })
- except:
- continue
- return jsonify(sorted(languages_dicts, key=itemgetter('name')))
-
- result = TableSettingsLanguages.select(TableSettingsLanguages.name,
- TableSettingsLanguages.code2,
- TableSettingsLanguages.enabled)\
- .order_by(TableSettingsLanguages.name).dicts()
- result = list(result)
- for item in result:
- item['enabled'] = item['enabled'] == 1
- return jsonify(result)
-
-
-class LanguagesProfiles(Resource):
- @authenticate
- def get(self):
- return jsonify(get_profiles_list())
-
-
-class Notifications(Resource):
- @authenticate
- def patch(self):
- url = request.form.get("url")
-
- asset = apprise.AppriseAsset(async_mode=False)
-
- apobj = apprise.Apprise(asset=asset)
-
- apobj.add(url)
-
- apobj.notify(
- title='Bazarr test notification',
- body='Test notification'
- )
-
- return '', 204
-
-
-class Searches(Resource):
- @authenticate
- def get(self):
- query = request.args.get('query')
- search_list = []
-
- if query:
- if settings.general.getboolean('use_sonarr'):
- # Get matching series
- series = TableShows.select(TableShows.title,
- TableShows.sonarrSeriesId,
- TableShows.year)\
- .where(TableShows.title.contains(query))\
- .order_by(TableShows.title)\
- .dicts()
- series = list(series)
- search_list += series
-
- if settings.general.getboolean('use_radarr'):
- # Get matching movies
- movies = TableMovies.select(TableMovies.title,
- TableMovies.radarrId,
- TableMovies.year) \
- .where(TableMovies.title.contains(query)) \
- .order_by(TableMovies.title) \
- .dicts()
- movies = list(movies)
- search_list += movies
-
- return jsonify(search_list)
-
-
-class SystemSettings(Resource):
- @authenticate
- def get(self):
- data = get_settings()
-
- notifications = TableSettingsNotifier.select().order_by(TableSettingsNotifier.name).dicts()
- notifications = list(notifications)
- for i, item in enumerate(notifications):
- item["enabled"] = item["enabled"] == 1
- notifications[i] = item
-
- data['notifications'] = dict()
- data['notifications']['providers'] = notifications
-
- return jsonify(data)
-
- @authenticate
- def post(self):
- enabled_languages = request.form.getlist('languages-enabled')
- if len(enabled_languages) != 0:
- TableSettingsLanguages.update({
- TableSettingsLanguages.enabled: 0
- }).execute()
- for code in enabled_languages:
- TableSettingsLanguages.update({
- TableSettingsLanguages.enabled: 1
- })\
- .where(TableSettingsLanguages.code2 == code)\
- .execute()
- event_stream("languages")
-
- languages_profiles = request.form.get('languages-profiles')
- if languages_profiles:
- existing_ids = TableLanguagesProfiles.select(TableLanguagesProfiles.profileId).dicts()
- existing_ids = list(existing_ids)
- existing = [x['profileId'] for x in existing_ids]
- for item in json.loads(languages_profiles):
- if item['profileId'] in existing:
- # Update existing profiles
- TableLanguagesProfiles.update({
- TableLanguagesProfiles.name: item['name'],
- TableLanguagesProfiles.cutoff: item['cutoff'] if item['cutoff'] != 'null' else None,
- TableLanguagesProfiles.items: json.dumps(item['items'])
- })\
- .where(TableLanguagesProfiles.profileId == item['profileId'])\
- .execute()
- existing.remove(item['profileId'])
- else:
- # Add new profiles
- TableLanguagesProfiles.insert({
- TableLanguagesProfiles.profileId: item['profileId'],
- TableLanguagesProfiles.name: item['name'],
- TableLanguagesProfiles.cutoff: item['cutoff'] if item['cutoff'] != 'null' else None,
- TableLanguagesProfiles.items: json.dumps(item['items'])
- }).execute()
- for profileId in existing:
- # Unassign this profileId from series and movies
- TableShows.update({
- TableShows.profileId: None
- }).where(TableShows.profileId == profileId).execute()
- TableMovies.update({
- TableMovies.profileId: None
- }).where(TableMovies.profileId == profileId).execute()
- # Remove deleted profiles
- TableLanguagesProfiles.delete().where(TableLanguagesProfiles.profileId == profileId).execute()
-
- update_profile_id_list()
- event_stream("languages")
-
- if settings.general.getboolean('use_sonarr'):
- scheduler.add_job(list_missing_subtitles, kwargs={'send_event': False})
- if settings.general.getboolean('use_radarr'):
- scheduler.add_job(list_missing_subtitles_movies, kwargs={'send_event': False})
-
- # Update Notification
- notifications = request.form.getlist('notifications-providers')
- for item in notifications:
- item = json.loads(item)
- TableSettingsNotifier.update({
- TableSettingsNotifier.enabled: item['enabled'],
- TableSettingsNotifier.url: item['url']
- }).where(TableSettingsNotifier.name == item['name']).execute()
-
- save_settings(zip(request.form.keys(), request.form.listvalues()))
- event_stream("settings")
- return '', 204
-
-
-class SystemTasks(Resource):
- @authenticate
- def get(self):
- taskid = request.args.get('taskid')
-
- task_list = scheduler.get_task_list()
-
- if taskid:
- for item in task_list:
- if item['job_id'] == taskid:
- task_list = [item]
- continue
-
- return jsonify(data=task_list)
-
- @authenticate
- def post(self):
- taskid = request.form.get('taskid')
-
- scheduler.execute_job_now(taskid)
-
- return '', 204
-
-
-class SystemLogs(Resource):
- @authenticate
- def get(self):
- logs = []
- with io.open(os.path.join(args.config_dir, 'log', 'bazarr.log'), encoding='UTF-8') as file:
- raw_lines = file.read()
- lines = raw_lines.split('|\n')
- for line in lines:
- if line == '':
- continue
- raw_message = line.split('|')
- raw_message_len = len(raw_message)
- if raw_message_len > 3:
- log = dict()
- log["timestamp"] = raw_message[0]
- log["type"] = raw_message[1].rstrip()
- log["message"] = raw_message[3]
- if raw_message_len > 4 and raw_message[4] != '\n':
- log['exception'] = raw_message[4].strip('\'').replace(' ', '\u2003\u2003')
- logs.append(log)
-
- logs.reverse()
- return jsonify(data=logs)
-
- @authenticate
- def delete(self):
- empty_log()
- return '', 204
-
-
-class SystemStatus(Resource):
- @authenticate
- def get(self):
- system_status = {}
- system_status.update({'bazarr_version': os.environ["BAZARR_VERSION"]})
- system_status.update({'sonarr_version': get_sonarr_info.version()})
- system_status.update({'radarr_version': get_radarr_info.version()})
- system_status.update({'operating_system': platform.platform()})
- system_status.update({'python_version': platform.python_version()})
- system_status.update({'bazarr_directory': os.path.dirname(os.path.dirname(__file__))})
- system_status.update({'bazarr_config_directory': args.config_dir})
- system_status.update({'start_time': startTime})
- return jsonify(data=system_status)
-
-
-class SystemHealth(Resource):
- @authenticate
- def get(self):
- return jsonify(data=get_health_issues())
-
-
-class SystemReleases(Resource):
- @authenticate
- def get(self):
- filtered_releases = []
- try:
- with io.open(os.path.join(args.config_dir, 'config', 'releases.txt'), 'r', encoding='UTF-8') as f:
- releases = json.loads(f.read())
-
- for release in releases:
- if settings.general.branch == 'master' and not release['prerelease']:
- filtered_releases.append(release)
- elif settings.general.branch != 'master' and any(not x['prerelease'] for x in filtered_releases):
- continue
- elif settings.general.branch != 'master':
- filtered_releases.append(release)
- if settings.general.branch == 'master':
- filtered_releases = filtered_releases[:5]
-
- current_version = os.environ["BAZARR_VERSION"]
-
- for i, release in enumerate(filtered_releases):
- body = release['body'].replace('- ', '').split('\n')[1:]
- filtered_releases[i] = {"body": body,
- "name": release['name'],
- "date": release['date'][:10],
- "prerelease": release['prerelease'],
- "current": release['name'].lstrip('v') == current_version}
-
- except Exception as e:
- logging.exception(
- 'BAZARR cannot parse releases caching file: ' + os.path.join(args.config_dir, 'config', 'releases.txt'))
- return jsonify(data=filtered_releases)
-
-
-class Series(Resource):
- @authenticate
- def get(self):
- start = request.args.get('start') or 0
- length = request.args.get('length') or -1
- seriesId = request.args.getlist('seriesid[]')
-
- count = TableShows.select().count()
-
- if len(seriesId) != 0:
- result = TableShows.select()\
- .where(TableShows.sonarrSeriesId.in_(seriesId))\
- .order_by(TableShows.sortTitle).dicts()
- else:
- result = TableShows.select().order_by(TableShows.sortTitle).limit(length).offset(start).dicts()
-
- result = list(result)
-
- for item in result:
- postprocessSeries(item)
-
- # Add missing subtitles episode count
- episodes_missing_conditions = [(TableEpisodes.sonarrSeriesId == item['sonarrSeriesId']),
- (TableEpisodes.missing_subtitles != '[]')]
- episodes_missing_conditions += get_exclusion_clause('series')
-
- episodeMissingCount = TableEpisodes.select(TableShows.tags,
- TableEpisodes.monitored,
- TableShows.seriesType)\
- .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .where(reduce(operator.and_, episodes_missing_conditions))\
- .count()
- item.update({"episodeMissingCount": episodeMissingCount})
-
- # Add episode count
- episodeFileCount = TableEpisodes.select(TableShows.tags,
- TableEpisodes.monitored,
- TableShows.seriesType)\
- .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .where(TableEpisodes.sonarrSeriesId == item['sonarrSeriesId'])\
- .count()
- item.update({"episodeFileCount": episodeFileCount})
-
- return jsonify(data=result, total=count)
-
- @authenticate
- def post(self):
- seriesIdList = request.form.getlist('seriesid')
- profileIdList = request.form.getlist('profileid')
-
- for idx in range(len(seriesIdList)):
- seriesId = seriesIdList[idx]
- profileId = profileIdList[idx]
-
- if profileId in None_Keys:
- profileId = None
- else:
- try:
- profileId = int(profileId)
- except Exception:
- return '', 400
-
- TableShows.update({
- TableShows.profileId: profileId
- })\
- .where(TableShows.sonarrSeriesId == seriesId)\
- .execute()
-
- list_missing_subtitles(no=seriesId, send_event=False)
-
- event_stream(type='series', payload=seriesId)
-
- episode_id_list = TableEpisodes\
- .select(TableEpisodes.sonarrEpisodeId)\
- .where(TableEpisodes.sonarrSeriesId == seriesId)\
- .dicts()
-
- for item in episode_id_list:
- event_stream(type='episode-wanted', payload=item['sonarrEpisodeId'])
-
- event_stream(type='badges')
-
- return '', 204
-
- @authenticate
- def patch(self):
- seriesid = request.form.get('seriesid')
- action = request.form.get('action')
- if action == "scan-disk":
- series_scan_subtitles(seriesid)
- return '', 204
- elif action == "search-missing":
- series_download_subtitles(seriesid)
- return '', 204
- elif action == "search-wanted":
- wanted_search_missing_subtitles_series()
- return '', 204
-
- return '', 400
-
-
-class Episodes(Resource):
- @authenticate
- def get(self):
- seriesId = request.args.getlist('seriesid[]')
- episodeId = request.args.getlist('episodeid[]')
-
- if len(episodeId) > 0:
- result = TableEpisodes.select().where(TableEpisodes.sonarrEpisodeId.in_(episodeId)).dicts()
- elif len(seriesId) > 0:
- result = TableEpisodes.select()\
- .where(TableEpisodes.sonarrSeriesId.in_(seriesId))\
- .order_by(TableEpisodes.season.desc(), TableEpisodes.episode.desc())\
- .dicts()
- else:
- return "Series or Episode ID not provided", 400
-
- result = list(result)
- for item in result:
- postprocessEpisode(item)
-
- return jsonify(data=result)
-
-
-# PATCH: Download Subtitles
-# POST: Upload Subtitles
-# DELETE: Delete Subtitles
-class EpisodesSubtitles(Resource):
- @authenticate
- def patch(self):
- sonarrSeriesId = request.args.get('seriesid')
- sonarrEpisodeId = request.args.get('episodeid')
- episodeInfo = TableEpisodes.select(TableEpisodes.title,
- TableEpisodes.path,
- TableEpisodes.scene_name,
- TableEpisodes.audio_language)\
- .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
- .dicts()\
- .get()
-
- title = episodeInfo['title']
- episodePath = path_mappings.path_replace(episodeInfo['path'])
- sceneName = episodeInfo['scene_name']
- audio_language = episodeInfo['audio_language']
- if sceneName is None: sceneName = "None"
-
- language = request.form.get('language')
- hi = request.form.get('hi').capitalize()
- forced = request.form.get('forced').capitalize()
-
- providers_list = get_providers()
- providers_auth = get_providers_auth()
-
- audio_language_list = get_audio_profile_languages(episode_id=sonarrEpisodeId)
- if len(audio_language_list) > 0:
- audio_language = audio_language_list[0]['name']
- else:
- audio_language = None
-
- try:
- result = download_subtitle(episodePath, language, audio_language, hi, forced, providers_list,
- providers_auth, sceneName, title, 'series')
- if result is not None:
- message = result[0]
- path = result[1]
- forced = result[5]
- if result[8]:
- language_code = result[2] + ":hi"
- elif forced:
- language_code = result[2] + ":forced"
- else:
- language_code = result[2]
- provider = result[3]
- score = result[4]
- subs_id = result[6]
- subs_path = result[7]
- history_log(1, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score, subs_id,
- subs_path)
- send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
- store_subtitles(path, episodePath)
- else:
- event_stream(type='episode', payload=sonarrEpisodeId)
-
- except OSError:
- pass
-
- return '', 204
-
- @authenticate
- def post(self):
- sonarrSeriesId = request.args.get('seriesid')
- sonarrEpisodeId = request.args.get('episodeid')
- episodeInfo = TableEpisodes.select(TableEpisodes.title,
- TableEpisodes.path,
- TableEpisodes.scene_name,
- TableEpisodes.audio_language)\
- .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
- .dicts()\
- .get()
-
- title = episodeInfo['title']
- episodePath = path_mappings.path_replace(episodeInfo['path'])
- sceneName = episodeInfo['scene_name']
- audio_language = episodeInfo['audio_language']
- if sceneName is None: sceneName = "None"
-
- language = request.form.get('language')
- forced = True if request.form.get('forced') == 'true' else False
- hi = True if request.form.get('hi') == 'true' else False
- subFile = request.files.get('file')
-
- _, ext = os.path.splitext(subFile.filename)
-
- if ext not in SUBTITLE_EXTENSIONS:
- raise ValueError('A subtitle of an invalid format was uploaded.')
-
- try:
- result = manual_upload_subtitle(path=episodePath,
- language=language,
- forced=forced,
- hi=hi,
- title=title,
- scene_name=sceneName,
- media_type='series',
- subtitle=subFile,
- audio_language=audio_language)
-
- if result is not None:
- message = result[0]
- path = result[1]
- subs_path = result[2]
- if hi:
- language_code = language + ":hi"
- elif forced:
- language_code = language + ":forced"
- else:
- language_code = language
- provider = "manual"
- score = 360
- history_log(4, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score,
- subtitles_path=subs_path)
- if not settings.general.getboolean('dont_notify_manual_actions'):
- send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
- store_subtitles(path, episodePath)
-
- except OSError:
- pass
-
- return '', 204
-
- @authenticate
- def delete(self):
- sonarrSeriesId = request.args.get('seriesid')
- sonarrEpisodeId = request.args.get('episodeid')
- episodeInfo = TableEpisodes.select(TableEpisodes.title,
- TableEpisodes.path,
- TableEpisodes.scene_name,
- TableEpisodes.audio_language)\
- .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
- .dicts()\
- .get()
-
- episodePath = path_mappings.path_replace(episodeInfo['path'])
-
- language = request.form.get('language')
- forced = request.form.get('forced')
- hi = request.form.get('hi')
- subtitlesPath = request.form.get('path')
-
- subtitlesPath = path_mappings.path_replace_reverse(subtitlesPath)
-
- result = delete_subtitles(media_type='series',
- language=language,
- forced=forced,
- hi=hi,
- media_path=episodePath,
- subtitles_path=subtitlesPath,
- sonarr_series_id=sonarrSeriesId,
- sonarr_episode_id=sonarrEpisodeId)
-
- return '', 204
-
-
-class Movies(Resource):
- @authenticate
- def get(self):
- start = request.args.get('start') or 0
- length = request.args.get('length') or -1
- radarrId = request.args.getlist('radarrid[]')
-
- count = TableMovies.select().count()
-
- if len(radarrId) != 0:
- result = TableMovies.select()\
- .where(TableMovies.radarrId.in_(radarrId))\
- .order_by(TableMovies.sortTitle)\
- .dicts()
- else:
- result = TableMovies.select().order_by(TableMovies.sortTitle).limit(length).offset(start).dicts()
- result = list(result)
- for item in result:
- postprocessMovie(item)
-
- return jsonify(data=result, total=count)
-
- @authenticate
- def post(self):
- radarrIdList = request.form.getlist('radarrid')
- profileIdList = request.form.getlist('profileid')
-
- for idx in range(len(radarrIdList)):
- radarrId = radarrIdList[idx]
- profileId = profileIdList[idx]
-
- if profileId in None_Keys:
- profileId = None
- else:
- try:
- profileId = int(profileId)
- except Exception:
- return '', 400
-
- TableMovies.update({
- TableMovies.profileId: profileId
- })\
- .where(TableMovies.radarrId == radarrId)\
- .execute()
-
- list_missing_subtitles_movies(no=radarrId, send_event=False)
-
- event_stream(type='movie', payload=radarrId)
- event_stream(type='movie-wanted', payload=radarrId)
- event_stream(type='badges')
-
- return '', 204
-
- @authenticate
- def patch(self):
- radarrid = request.form.get('radarrid')
- action = request.form.get('action')
- if action == "scan-disk":
- movies_scan_subtitles(radarrid)
- return '', 204
- elif action == "search-missing":
- movies_download_subtitles(radarrid)
- return '', 204
- elif action == "search-wanted":
- wanted_search_missing_subtitles_movies()
- return '', 204
-
- return '', 400
-
-
-"""
-:param language: Alpha2 language code
-"""
-
-
-class MoviesSubtitles(Resource):
- @authenticate
- def patch(self):
- # Download
- radarrId = request.args.get('radarrid')
-
- movieInfo = TableMovies.select(TableMovies.title,
- TableMovies.path,
- TableMovies.sceneName,
- TableMovies.audio_language)\
- .where(TableMovies.radarrId == radarrId)\
- .dicts()\
- .get()
-
- moviePath = path_mappings.path_replace_movie(movieInfo['path'])
- sceneName = movieInfo['sceneName']
- if sceneName is None: sceneName = 'None'
-
- title = movieInfo['title']
- audio_language = movieInfo['audio_language']
-
- language = request.form.get('language')
- hi = request.form.get('hi').capitalize()
- forced = request.form.get('forced').capitalize()
-
- providers_list = get_providers()
- providers_auth = get_providers_auth()
-
- audio_language_list = get_audio_profile_languages(movie_id=radarrId)
- if len(audio_language_list) > 0:
- audio_language = audio_language_list[0]['name']
- else:
- audio_language = None
-
- try:
- result = download_subtitle(moviePath, language, audio_language, hi, forced, providers_list,
- providers_auth, sceneName, title, 'movie')
- if result is not None:
- message = result[0]
- path = result[1]
- forced = result[5]
- if result[8]:
- language_code = result[2] + ":hi"
- elif forced:
- language_code = result[2] + ":forced"
- else:
- language_code = result[2]
- provider = result[3]
- score = result[4]
- subs_id = result[6]
- subs_path = result[7]
- history_log_movie(1, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
- send_notifications_movie(radarrId, message)
- store_subtitles_movie(path, moviePath)
- else:
- event_stream(type='movie', payload=radarrId)
- except OSError:
- pass
-
- return '', 204
-
- @authenticate
- def post(self):
- # Upload
- # TODO: Support Multiply Upload
- radarrId = request.args.get('radarrid')
- movieInfo = TableMovies.select(TableMovies.title,
- TableMovies.path,
- TableMovies.sceneName,
- TableMovies.audio_language) \
- .where(TableMovies.radarrId == radarrId) \
- .dicts() \
- .get()
-
- moviePath = path_mappings.path_replace_movie(movieInfo['path'])
- sceneName = movieInfo['sceneName']
- if sceneName is None: sceneName = 'None'
-
- title = movieInfo['title']
- audioLanguage = movieInfo['audio_language']
-
- language = request.form.get('language')
- forced = True if request.form.get('forced') == 'true' else False
- hi = True if request.form.get('hi') == 'true' else False
- subFile = request.files.get('file')
-
- _, ext = os.path.splitext(subFile.filename)
-
- if ext not in SUBTITLE_EXTENSIONS:
- raise ValueError('A subtitle of an invalid format was uploaded.')
-
- try:
- result = manual_upload_subtitle(path=moviePath,
- language=language,
- forced=forced,
- hi=hi,
- title=title,
- scene_name=sceneName,
- media_type='movie',
- subtitle=subFile,
- audio_language=audioLanguage)
-
- if result is not None:
- message = result[0]
- path = result[1]
- subs_path = result[2]
- if hi:
- language_code = language + ":hi"
- elif forced:
- language_code = language + ":forced"
- else:
- language_code = language
- provider = "manual"
- score = 120
- history_log_movie(4, radarrId, message, path, language_code, provider, score, subtitles_path=subs_path)
- if not settings.general.getboolean('dont_notify_manual_actions'):
- send_notifications_movie(radarrId, message)
- store_subtitles_movie(path, moviePath)
- except OSError:
- pass
-
- return '', 204
-
- @authenticate
- def delete(self):
- # Delete
- radarrId = request.args.get('radarrid')
- movieInfo = TableMovies.select(TableMovies.path) \
- .where(TableMovies.radarrId == radarrId) \
- .dicts() \
- .get()
-
- moviePath = path_mappings.path_replace_movie(movieInfo['path'])
-
- language = request.form.get('language')
- forced = request.form.get('forced')
- hi = request.form.get('hi')
- subtitlesPath = request.form.get('path')
-
- subtitlesPath = path_mappings.path_replace_reverse_movie(subtitlesPath)
-
- result = delete_subtitles(media_type='movie',
- language=language,
- forced=forced,
- hi=hi,
- media_path=moviePath,
- subtitles_path=subtitlesPath,
- radarr_id=radarrId)
- if result:
- return '', 202
- else:
- return '', 204
-
-
-class Providers(Resource):
- @authenticate
- def get(self):
- history = request.args.get('history')
- if history and history not in False_Keys:
- providers = list(TableHistory.select(TableHistory.provider)
- .where(TableHistory.provider != None and TableHistory.provider != "manual")
- .dicts())
- providers += list(TableHistoryMovie.select(TableHistoryMovie.provider)
- .where(TableHistoryMovie.provider != None and TableHistoryMovie.provider != "manual")
- .dicts())
- providers_list = list(set([x['provider'] for x in providers]))
- providers_dicts = []
- for provider in providers_list:
- providers_dicts.append({
- 'name': provider,
- 'status': 'History',
- 'retry': '-'
- })
- return jsonify(data=sorted(providers_dicts, key=itemgetter('name')))
-
- throttled_providers = list_throttled_providers()
-
- providers = list()
- for provider in throttled_providers:
- providers.append({
- "name": provider[0],
- "status": provider[1] if provider[1] is not None else "Good",
- "retry": provider[2] if provider[2] != "now" else "-"
- })
- return jsonify(data=providers)
-
- @authenticate
- def post(self):
- action = request.form.get('action')
-
- if action == 'reset':
- reset_throttled_providers()
- return '', 204
-
- return '', 400
-
-
-class ProviderMovies(Resource):
- @authenticate
- def get(self):
- # Manual Search
- radarrId = request.args.get('radarrid')
- movieInfo = TableMovies.select(TableMovies.title,
- TableMovies.path,
- TableMovies.sceneName,
- TableMovies.profileId) \
- .where(TableMovies.radarrId == radarrId) \
- .dicts() \
- .get()
-
- title = movieInfo['title']
- moviePath = path_mappings.path_replace_movie(movieInfo['path'])
- sceneName = movieInfo['sceneName']
- profileId = movieInfo['profileId']
- if sceneName is None: sceneName = "None"
-
- providers_list = get_providers()
- providers_auth = get_providers_auth()
-
- data = manual_search(moviePath, profileId, providers_list, providers_auth, sceneName, title,
- 'movie')
- if not data:
- data = []
- return jsonify(data=data)
-
- @authenticate
- def post(self):
- # Manual Download
- radarrId = request.args.get('radarrid')
- movieInfo = TableMovies.select(TableMovies.title,
- TableMovies.path,
- TableMovies.sceneName,
- TableMovies.audio_language) \
- .where(TableMovies.radarrId == radarrId) \
- .dicts() \
- .get()
-
- title = movieInfo['title']
- moviePath = path_mappings.path_replace_movie(movieInfo['path'])
- sceneName = movieInfo['sceneName']
- if sceneName is None: sceneName = "None"
- audio_language = movieInfo['audio_language']
-
- language = request.form.get('language')
- hi = request.form.get('hi').capitalize()
- forced = request.form.get('forced').capitalize()
- selected_provider = request.form.get('provider')
- subtitle = request.form.get('subtitle')
-
- providers_auth = get_providers_auth()
-
- audio_language_list = get_audio_profile_languages(movie_id=radarrId)
- if len(audio_language_list) > 0:
- audio_language = audio_language_list[0]['name']
- else:
- audio_language = 'None'
-
- try:
- result = manual_download_subtitle(moviePath, language, audio_language, hi, forced, subtitle,
- selected_provider, providers_auth, sceneName, title, 'movie')
- if result is not None:
- message = result[0]
- path = result[1]
- forced = result[5]
- if result[8]:
- language_code = result[2] + ":hi"
- elif forced:
- language_code = result[2] + ":forced"
- else:
- language_code = result[2]
- provider = result[3]
- score = result[4]
- subs_id = result[6]
- subs_path = result[7]
- history_log_movie(2, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
- if not settings.general.getboolean('dont_notify_manual_actions'):
- send_notifications_movie(radarrId, message)
- store_subtitles_movie(path, moviePath)
- except OSError:
- pass
-
- return '', 204
-
-
-class ProviderEpisodes(Resource):
- @authenticate
- def get(self):
- # Manual Search
- sonarrEpisodeId = request.args.get('episodeid')
- episodeInfo = TableEpisodes.select(TableEpisodes.title,
- TableEpisodes.path,
- TableEpisodes.scene_name,
- TableShows.profileId) \
- .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId) \
- .dicts() \
- .get()
-
- title = episodeInfo['title']
- episodePath = path_mappings.path_replace(episodeInfo['path'])
- sceneName = episodeInfo['scene_name']
- profileId = episodeInfo['profileId']
- if sceneName is None: sceneName = "None"
-
- providers_list = get_providers()
- providers_auth = get_providers_auth()
-
- data = manual_search(episodePath, profileId, providers_list, providers_auth, sceneName, title,
- 'series')
- if not data:
- data = []
- return jsonify(data=data)
-
- @authenticate
- def post(self):
- # Manual Download
- sonarrSeriesId = request.args.get('seriesid')
- sonarrEpisodeId = request.args.get('episodeid')
- episodeInfo = TableEpisodes.select(TableEpisodes.title,
- TableEpisodes.path,
- TableEpisodes.scene_name) \
- .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId) \
- .dicts() \
- .get()
-
- title = episodeInfo['title']
- episodePath = path_mappings.path_replace(episodeInfo['path'])
- sceneName = episodeInfo['scene_name']
- if sceneName is None: sceneName = "None"
-
- language = request.form.get('language')
- hi = request.form.get('hi').capitalize()
- forced = request.form.get('forced').capitalize()
- selected_provider = request.form.get('provider')
- subtitle = request.form.get('subtitle')
- providers_auth = get_providers_auth()
-
- audio_language_list = get_audio_profile_languages(episode_id=sonarrEpisodeId)
- if len(audio_language_list) > 0:
- audio_language = audio_language_list[0]['name']
- else:
- audio_language = 'None'
-
- try:
- result = manual_download_subtitle(episodePath, language, audio_language, hi, forced, subtitle,
- selected_provider, providers_auth, sceneName, title, 'series')
- if result is not None:
- message = result[0]
- path = result[1]
- forced = result[5]
- if result[8]:
- language_code = result[2] + ":hi"
- elif forced:
- language_code = result[2] + ":forced"
- else:
- language_code = result[2]
- provider = result[3]
- score = result[4]
- subs_id = result[6]
- subs_path = result[7]
- history_log(2, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score, subs_id,
- subs_path)
- if not settings.general.getboolean('dont_notify_manual_actions'):
- send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
- store_subtitles(path, episodePath)
- return result, 201
- except OSError:
- pass
-
- return '', 204
-
-
-class EpisodesHistory(Resource):
- @authenticate
- def get(self):
- start = request.args.get('start') or 0
- length = request.args.get('length') or -1
- episodeid = request.args.get('episodeid')
-
- upgradable_episodes_not_perfect = []
- if settings.general.getboolean('upgrade_subs'):
- days_to_upgrade_subs = settings.general.days_to_upgrade_subs
- minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
- datetime.datetime(1970, 1, 1)).total_seconds()
-
- if settings.general.getboolean('upgrade_manual'):
- query_actions = [1, 2, 3, 6]
- else:
- query_actions = [1, 3]
-
- upgradable_episodes_conditions = [(TableHistory.action.in_(query_actions)),
- (TableHistory.timestamp > minimum_timestamp),
- (TableHistory.score is not None)]
- upgradable_episodes_conditions += get_exclusion_clause('series')
- upgradable_episodes = TableHistory.select(TableHistory.video_path,
- fn.MAX(TableHistory.timestamp).alias('timestamp'),
- TableHistory.score,
- TableShows.tags,
- TableEpisodes.monitored,
- TableShows.seriesType)\
- .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
- .join(TableShows, on=(TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .where(reduce(operator.and_, upgradable_episodes_conditions))\
- .group_by(TableHistory.video_path)\
- .dicts()
- upgradable_episodes = list(upgradable_episodes)
- for upgradable_episode in upgradable_episodes:
- if upgradable_episode['timestamp'] > minimum_timestamp:
- try:
- int(upgradable_episode['score'])
- except ValueError:
- pass
- else:
- if int(upgradable_episode['score']) < 360:
- upgradable_episodes_not_perfect.append(upgradable_episode)
-
- query_conditions = [(TableEpisodes.title is not None)]
- if episodeid:
- query_conditions.append((TableEpisodes.sonarrEpisodeId == episodeid))
- query_condition = reduce(operator.and_, query_conditions)
- episode_history = TableHistory.select(TableHistory.id,
- TableShows.title.alias('seriesTitle'),
- TableEpisodes.monitored,
- TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
- TableEpisodes.title.alias('episodeTitle'),
- TableHistory.timestamp,
- TableHistory.subs_id,
- TableHistory.description,
- TableHistory.sonarrSeriesId,
- TableEpisodes.path,
- TableHistory.language,
- TableHistory.score,
- TableShows.tags,
- TableHistory.action,
- TableHistory.subtitles_path,
- TableHistory.sonarrEpisodeId,
- TableHistory.provider,
- TableShows.seriesType)\
- .join(TableShows, on=(TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
- .where(query_condition)\
- .order_by(TableHistory.timestamp.desc())\
- .limit(length)\
- .offset(start)\
- .dicts()
- episode_history = list(episode_history)
-
- blacklist_db = TableBlacklist.select(TableBlacklist.provider, TableBlacklist.subs_id).dicts()
- blacklist_db = list(blacklist_db)
-
- for item in episode_history:
- # Mark episode as upgradable or not
- item.update({"upgradable": False})
- if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score']),
- "tags": str(item['tags']), "monitored": str(item['monitored']),
- "seriesType": str(item['seriesType'])} in upgradable_episodes_not_perfect:
- if os.path.isfile(path_mappings.path_replace(item['subtitles_path'])):
- item.update({"upgradable": True})
-
- del item['path']
-
- postprocessEpisode(item)
-
- if item['score']:
- item['score'] = str(round((int(item['score']) * 100 / 360), 2)) + "%"
-
- # Make timestamp pretty
- if item['timestamp']:
- item["raw_timestamp"] = int(item['timestamp'])
- item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
- item['timestamp'] = pretty.date(item["raw_timestamp"])
-
- # Check if subtitles is blacklisted
- item.update({"blacklisted": False})
- if item['action'] not in [0, 4, 5]:
- for blacklisted_item in blacklist_db:
- if blacklisted_item['provider'] == item['provider'] and \
- blacklisted_item['subs_id'] == item['subs_id']:
- item.update({"blacklisted": True})
- break
-
- count = TableHistory.select()\
- .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
- .where(TableEpisodes.title is not None).count()
-
- return jsonify(data=episode_history, total=count)
-
-
-class MoviesHistory(Resource):
- @authenticate
- def get(self):
- start = request.args.get('start') or 0
- length = request.args.get('length') or -1
- radarrid = request.args.get('radarrid')
-
- upgradable_movies = []
- upgradable_movies_not_perfect = []
- if settings.general.getboolean('upgrade_subs'):
- days_to_upgrade_subs = settings.general.days_to_upgrade_subs
- minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
- datetime.datetime(1970, 1, 1)).total_seconds()
-
- if settings.general.getboolean('upgrade_manual'):
- query_actions = [1, 2, 3, 6]
- else:
- query_actions = [1, 3]
-
- upgradable_movies_conditions = [(TableHistoryMovie.action.in_(query_actions)),
- (TableHistoryMovie.timestamp > minimum_timestamp),
- (TableHistoryMovie.score is not None)]
- upgradable_movies_conditions += get_exclusion_clause('movie')
- upgradable_movies = TableHistoryMovie.select(TableHistoryMovie.video_path,
- fn.MAX(TableHistoryMovie.timestamp).alias('timestamp'),
- TableHistoryMovie.score,
- TableMovies.tags,
- TableMovies.monitored)\
- .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
- .where(reduce(operator.and_, upgradable_movies_conditions))\
- .group_by(TableHistoryMovie.video_path)\
- .dicts()
- upgradable_movies = list(upgradable_movies)
-
- for upgradable_movie in upgradable_movies:
- if upgradable_movie['timestamp'] > minimum_timestamp:
- try:
- int(upgradable_movie['score'])
- except ValueError:
- pass
- else:
- if int(upgradable_movie['score']) < 120:
- upgradable_movies_not_perfect.append(upgradable_movie)
-
- query_conditions = [(TableMovies.title is not None)]
- if radarrid:
- query_conditions.append((TableMovies.radarrId == radarrid))
- query_condition = reduce(operator.and_, query_conditions)
-
- movie_history = TableHistoryMovie.select(TableHistoryMovie.id,
- TableHistoryMovie.action,
- TableMovies.title,
- TableHistoryMovie.timestamp,
- TableHistoryMovie.description,
- TableHistoryMovie.radarrId,
- TableMovies.monitored,
- TableHistoryMovie.video_path.alias('path'),
- TableHistoryMovie.language,
- TableMovies.tags,
- TableHistoryMovie.score,
- TableHistoryMovie.subs_id,
- TableHistoryMovie.provider,
- TableHistoryMovie.subtitles_path)\
- .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
- .where(query_condition)\
- .order_by(TableHistoryMovie.timestamp.desc())\
- .limit(length)\
- .offset(start)\
- .dicts()
- movie_history = list(movie_history)
-
- blacklist_db = TableBlacklistMovie.select(TableBlacklistMovie.provider, TableBlacklistMovie.subs_id).dicts()
- blacklist_db = list(blacklist_db)
-
- for item in movie_history:
- # Mark movies as upgradable or not
- item.update({"upgradable": False})
- if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score']),
- "tags": str(item['tags']), "monitored": str(item['monitored'])} in upgradable_movies_not_perfect:
- if os.path.isfile(path_mappings.path_replace_movie(item['subtitles_path'])):
- item.update({"upgradable": True})
-
- del item['path']
-
- postprocessMovie(item)
-
- if item['score']:
- item['score'] = str(round((int(item['score']) * 100 / 120), 2)) + "%"
-
- # Make timestamp pretty
- if item['timestamp']:
- item["raw_timestamp"] = int(item['timestamp'])
- item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
- item['timestamp'] = pretty.date(item["raw_timestamp"])
-
- # Check if subtitles is blacklisted
- item.update({"blacklisted": False})
- if item['action'] not in [0, 4, 5]:
- for blacklisted_item in blacklist_db:
- if blacklisted_item['provider'] == item['provider'] and blacklisted_item['subs_id'] == item[
- 'subs_id']:
- item.update({"blacklisted": True})
- break
-
- count = TableHistoryMovie.select()\
- .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
- .where(TableMovies.title is not None)\
- .count()
-
- return jsonify(data=movie_history, total=count)
-
-
-class HistoryStats(Resource):
- @authenticate
- def get(self):
- timeframe = request.args.get('timeframe') or 'month'
- action = request.args.get('action') or 'All'
- provider = request.args.get('provider') or 'All'
- language = request.args.get('language') or 'All'
-
- # timeframe must be in ['week', 'month', 'trimester', 'year']
- if timeframe == 'year':
- delay = 364 * 24 * 60 * 60
- elif timeframe == 'trimester':
- delay = 90 * 24 * 60 * 60
- elif timeframe == 'month':
- delay = 30 * 24 * 60 * 60
- elif timeframe == 'week':
- delay = 6 * 24 * 60 * 60
-
- now = time.time()
- past = now - delay
-
- history_where_clauses = [(TableHistory.timestamp.between(past, now))]
- history_where_clauses_movie = [(TableHistoryMovie.timestamp.between(past, now))]
-
- if action != 'All':
- history_where_clauses.append((TableHistory.action == action))
- history_where_clauses_movie.append((TableHistoryMovie.action == action))
- else:
- history_where_clauses.append((TableHistory.action.in_([1, 2, 3])))
- history_where_clauses_movie.append((TableHistoryMovie.action.in_([1, 2, 3])))
-
- if provider != 'All':
- history_where_clauses.append((TableHistory.provider == provider))
- history_where_clauses_movie.append((TableHistoryMovie.provider == provider))
-
- if language != 'All':
- history_where_clauses.append((TableHistory.language == language))
- history_where_clauses_movie.append((TableHistoryMovie.language == language))
-
- history_where_clause = reduce(operator.and_, history_where_clauses)
- history_where_clause_movie = reduce(operator.and_, history_where_clauses_movie)
-
- data_series = TableHistory.select(fn.strftime('%Y-%m-%d', TableHistory.timestamp, 'unixepoch').alias('date'),
- fn.COUNT(TableHistory.id).alias('count'))\
- .where(history_where_clause) \
- .group_by(fn.strftime('%Y-%m-%d', TableHistory.timestamp, 'unixepoch'))\
- .dicts()
- data_series = list(data_series)
-
- data_movies = TableHistoryMovie.select(fn.strftime('%Y-%m-%d', TableHistoryMovie.timestamp, 'unixepoch').alias('date'),
- fn.COUNT(TableHistoryMovie.id).alias('count')) \
- .where(history_where_clause_movie) \
- .group_by(fn.strftime('%Y-%m-%d', TableHistoryMovie.timestamp, 'unixepoch')) \
- .dicts()
- data_movies = list(data_movies)
-
- for dt in rrule.rrule(rrule.DAILY,
- dtstart=datetime.datetime.now() - datetime.timedelta(seconds=delay),
- until=datetime.datetime.now()):
- if not any(d['date'] == dt.strftime('%Y-%m-%d') for d in data_series):
- data_series.append({'date': dt.strftime('%Y-%m-%d'), 'count': 0})
- if not any(d['date'] == dt.strftime('%Y-%m-%d') for d in data_movies):
- data_movies.append({'date': dt.strftime('%Y-%m-%d'), 'count': 0})
-
- sorted_data_series = sorted(data_series, key=lambda i: i['date'])
- sorted_data_movies = sorted(data_movies, key=lambda i: i['date'])
-
- return jsonify(series=sorted_data_series, movies=sorted_data_movies)
-
-
-# GET: Get Wanted Episodes
-class EpisodesWanted(Resource):
- @authenticate
- def get(self):
- episodeid = request.args.getlist('episodeid[]')
-
- wanted_conditions = [(TableEpisodes.missing_subtitles != '[]')]
- if len(episodeid) > 0:
- wanted_conditions.append((TableEpisodes.sonarrEpisodeId in episodeid))
- wanted_conditions += get_exclusion_clause('series')
- wanted_condition = reduce(operator.and_, wanted_conditions)
-
- if len(episodeid) > 0:
- data = TableEpisodes.select(TableShows.title.alias('seriesTitle'),
- TableEpisodes.monitored,
- TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
- TableEpisodes.title.alias('episodeTitle'),
- TableEpisodes.missing_subtitles,
- TableEpisodes.sonarrSeriesId,
- TableEpisodes.sonarrEpisodeId,
- TableEpisodes.scene_name.alias('sceneName'),
- TableShows.tags,
- TableEpisodes.failedAttempts,
- TableShows.seriesType)\
- .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .where(wanted_condition)\
- .dicts()
- else:
- start = request.args.get('start') or 0
- length = request.args.get('length') or -1
- data = TableEpisodes.select(TableShows.title.alias('seriesTitle'),
- TableEpisodes.monitored,
- TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
- TableEpisodes.title.alias('episodeTitle'),
- TableEpisodes.missing_subtitles,
- TableEpisodes.sonarrSeriesId,
- TableEpisodes.sonarrEpisodeId,
- TableEpisodes.scene_name.alias('sceneName'),
- TableShows.tags,
- TableEpisodes.failedAttempts,
- TableShows.seriesType)\
- .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .where(wanted_condition)\
- .order_by(TableEpisodes.rowid.desc())\
- .limit(length)\
- .offset(start)\
- .dicts()
- data = list(data)
-
- for item in data:
- postprocessEpisode(item)
-
- count_conditions = [(TableEpisodes.missing_subtitles != '[]')]
- count_conditions += get_exclusion_clause('series')
- count = TableEpisodes.select(TableShows.tags,
- TableShows.seriesType,
- TableEpisodes.monitored)\
- .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
- .where(reduce(operator.and_, count_conditions))\
- .count()
-
- return jsonify(data=data, total=count)
-
-
-# GET: Get Wanted Movies
-class MoviesWanted(Resource):
- @authenticate
- def get(self):
- radarrid = request.args.getlist("radarrid[]")
-
- wanted_conditions = [(TableMovies.missing_subtitles != '[]')]
- if len(radarrid) > 0:
- wanted_conditions.append((TableMovies.radarrId.in_(radarrid)))
- wanted_conditions += get_exclusion_clause('movie')
- wanted_condition = reduce(operator.and_, wanted_conditions)
-
- if len(radarrid) > 0:
- result = TableMovies.select(TableMovies.title,
- TableMovies.missing_subtitles,
- TableMovies.radarrId,
- TableMovies.sceneName,
- TableMovies.failedAttempts,
- TableMovies.tags,
- TableMovies.monitored)\
- .where(wanted_condition)\
- .dicts()
- else:
- start = request.args.get('start') or 0
- length = request.args.get('length') or -1
- result = TableMovies.select(TableMovies.title,
- TableMovies.missing_subtitles,
- TableMovies.radarrId,
- TableMovies.sceneName,
- TableMovies.failedAttempts,
- TableMovies.tags,
- TableMovies.monitored)\
- .where(wanted_condition)\
- .order_by(TableMovies.rowid.desc())\
- .limit(length)\
- .offset(start)\
- .dicts()
- result = list(result)
-
- for item in result:
- postprocessMovie(item)
-
- count_conditions = [(TableMovies.missing_subtitles != '[]')]
- count_conditions += get_exclusion_clause('movie')
- count = TableMovies.select(TableMovies.monitored,
- TableMovies.tags)\
- .where(reduce(operator.and_, count_conditions))\
- .count()
-
- return jsonify(data=result, total=count)
-
-
-# GET: get blacklist
-# POST: add blacklist
-# DELETE: remove blacklist
-class EpisodesBlacklist(Resource):
- @authenticate
- def get(self):
- start = request.args.get('start') or 0
- length = request.args.get('length') or -1
-
- data = TableBlacklist.select(TableShows.title.alias('seriesTitle'),
- TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
- TableEpisodes.title.alias('episodeTitle'),
- TableEpisodes.sonarrSeriesId,
- TableBlacklist.provider,
- TableBlacklist.subs_id,
- TableBlacklist.language,
- TableBlacklist.timestamp)\
- .join(TableEpisodes, on=(TableBlacklist.sonarr_episode_id == TableEpisodes.sonarrEpisodeId))\
- .join(TableShows, on=(TableBlacklist.sonarr_series_id == TableShows.sonarrSeriesId))\
- .order_by(TableBlacklist.timestamp.desc())\
- .limit(length)\
- .offset(start)\
- .dicts()
- data = list(data)
-
- for item in data:
- # Make timestamp pretty
- item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
- item.update({'timestamp': pretty.date(datetime.datetime.fromtimestamp(item['timestamp']))})
-
- postprocessEpisode(item)
-
- return jsonify(data=data)
-
- @authenticate
- def post(self):
- sonarr_series_id = int(request.args.get('seriesid'))
- sonarr_episode_id = int(request.args.get('episodeid'))
- provider = request.form.get('provider')
- subs_id = request.form.get('subs_id')
- language = request.form.get('language')
-
- episodeInfo = TableEpisodes.select(TableEpisodes.path)\
- .where(TableEpisodes.sonarrEpisodeId == sonarr_episode_id)\
- .dicts()\
- .get()
-
- media_path = episodeInfo['path']
- subtitles_path = request.form.get('subtitles_path')
-
- blacklist_log(sonarr_series_id=sonarr_series_id,
- sonarr_episode_id=sonarr_episode_id,
- provider=provider,
- subs_id=subs_id,
- language=language)
- delete_subtitles(media_type='series',
- language=language,
- forced=False,
- hi=False,
- media_path=path_mappings.path_replace(media_path),
- subtitles_path=subtitles_path,
- sonarr_series_id=sonarr_series_id,
- sonarr_episode_id=sonarr_episode_id)
- episode_download_subtitles(sonarr_episode_id)
- event_stream(type='episode-history')
- return '', 200
-
- @authenticate
- def delete(self):
- if request.args.get("all") == "true":
- blacklist_delete_all()
- else:
- provider = request.form.get('provider')
- subs_id = request.form.get('subs_id')
- blacklist_delete(provider=provider, subs_id=subs_id)
- return '', 204
-
-
-# GET: get blacklist
-# POST: add blacklist
-# DELETE: remove blacklist
-class MoviesBlacklist(Resource):
- @authenticate
- def get(self):
- start = request.args.get('start') or 0
- length = request.args.get('length') or -1
-
- data = TableBlacklistMovie.select(TableMovies.title,
- TableMovies.radarrId,
- TableBlacklistMovie.provider,
- TableBlacklistMovie.subs_id,
- TableBlacklistMovie.language,
- TableBlacklistMovie.timestamp)\
- .join(TableMovies, on=(TableBlacklistMovie.radarr_id == TableMovies.radarrId))\
- .order_by(TableBlacklistMovie.timestamp.desc())\
- .limit(length)\
- .offset(start)\
- .dicts()
- data = list(data)
-
- for item in data:
- postprocessMovie(item)
-
- # Make timestamp pretty
- item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
- item.update({'timestamp': pretty.date(datetime.datetime.fromtimestamp(item['timestamp']))})
-
- return jsonify(data=data)
-
- @authenticate
- def post(self):
- radarr_id = int(request.args.get('radarrid'))
- provider = request.form.get('provider')
- subs_id = request.form.get('subs_id')
- language = request.form.get('language')
- # TODO
- forced = False
- hi = False
-
- data = TableMovies.select(TableMovies.path).where(TableMovies.radarrId == radarr_id).dicts().get()
-
- media_path = data['path']
- subtitles_path = request.form.get('subtitles_path')
-
- blacklist_log_movie(radarr_id=radarr_id,
- provider=provider,
- subs_id=subs_id,
- language=language)
- delete_subtitles(media_type='movie',
- language=language,
- forced=forced,
- hi=hi,
- media_path=path_mappings.path_replace_movie(media_path),
- subtitles_path=subtitles_path,
- radarr_id=radarr_id)
- movies_download_subtitles(radarr_id)
- event_stream(type='movie-history')
- return '', 200
-
- @authenticate
- def delete(self):
- if request.args.get("all") == "true":
- blacklist_delete_all_movie()
- else:
- provider = request.form.get('provider')
- subs_id = request.form.get('subs_id')
- blacklist_delete_movie(provider=provider, subs_id=subs_id)
- return '', 200
-
-
-class Subtitles(Resource):
- @authenticate
- def patch(self):
- action = request.args.get('action')
-
- language = request.form.get('language')
- subtitles_path = request.form.get('path')
- media_type = request.form.get('type')
- id = request.form.get('id')
-
- if media_type == 'episode':
- subtitles_path = path_mappings.path_replace(subtitles_path)
- metadata = TableEpisodes.select(TableEpisodes.path, TableEpisodes.sonarrSeriesId)\
- .where(TableEpisodes.sonarrEpisodeId == id)\
- .dicts()\
- .get()
- video_path = path_mappings.path_replace(metadata['path'])
- else:
- subtitles_path = path_mappings.path_replace_movie(subtitles_path)
- metadata = TableMovies.select(TableMovies.path).where(TableMovies.radarrId == id).dicts().get()
- video_path = path_mappings.path_replace_movie(metadata['path'])
-
- if action == 'sync':
- if media_type == 'episode':
- subsync.sync(video_path=video_path, srt_path=subtitles_path,
- srt_lang=language, media_type='series', sonarr_series_id=metadata['sonarrSeriesId'],
- sonarr_episode_id=int(id))
- else:
- subsync.sync(video_path=video_path, srt_path=subtitles_path,
- srt_lang=language, media_type='movies', radarr_id=id)
- elif action == 'translate':
- dest_language = language
- forced = True if request.form.get('forced') == 'true' else False
- hi = True if request.form.get('hi') == 'true' else False
- result = translate_subtitles_file(video_path=video_path, source_srt_file=subtitles_path,
- to_lang=dest_language,
- forced=forced, hi=hi)
- if result:
- if media_type == 'episode':
- store_subtitles(path_mappings.path_replace_reverse(video_path), video_path)
- else:
- store_subtitles_movie(path_mappings.path_replace_reverse_movie(video_path), video_path)
- return '', 200
- else:
- return '', 404
- else:
- subtitles_apply_mods(language, subtitles_path, [action])
-
- # apply chmod if required
- chmod = int(settings.general.chmod, 8) if not sys.platform.startswith(
- 'win') and settings.general.getboolean('chmod_enabled') else None
- if chmod:
- os.chmod(subtitles_path, chmod)
-
- return '', 204
-
-
-class SubtitleNameInfo(Resource):
- @authenticate
- def get(self):
- names = request.args.getlist('filenames[]')
- results = []
- for name in names:
- opts = dict()
- opts['type'] = 'episode'
- guessit_result = guessit(name, options=opts)
- result = {}
- result['filename'] = name
- if 'subtitle_language' in guessit_result:
- result['subtitle_language'] = str(guessit_result['subtitle_language'])
-
- result['episode'] = 0
- if 'episode' in guessit_result:
- if isinstance(guessit_result['episode'], list):
- # for multiple episodes file, choose the first episode number
- if len(guessit_result['episode']):
- # make sure that guessit returned a list of more than 0 items
- result['episode'] = int(guessit_result['episode'][0])
- elif isinstance(guessit_result['episode'], (str, int)):
- # if single episode (should be int but just in case we cast it to int)
- result['episode'] = int(guessit_result['episode'])
-
- if 'season' in guessit_result:
- result['season'] = int(guessit_result['season'])
- else:
- result['season'] = 0
-
- results.append(result)
-
- return jsonify(data=results)
-
-
-class BrowseBazarrFS(Resource):
- @authenticate
- def get(self):
- path = request.args.get('path') or ''
- data = []
- try:
- result = browse_bazarr_filesystem(path)
- if result is None:
- raise ValueError
- except Exception:
- return jsonify([])
- for item in result['directories']:
- data.append({'name': item['name'], 'children': True, 'path': item['path']})
- return jsonify(data)
-
-
-class BrowseSonarrFS(Resource):
- @authenticate
- def get(self):
- path = request.args.get('path') or ''
- data = []
- try:
- result = browse_sonarr_filesystem(path)
- if result is None:
- raise ValueError
- except Exception:
- return jsonify([])
- for item in result['directories']:
- data.append({'name': item['name'], 'children': True, 'path': item['path']})
- return jsonify(data)
-
-
-class BrowseRadarrFS(Resource):
- @authenticate
- def get(self):
- path = request.args.get('path') or ''
- data = []
- try:
- result = browse_radarr_filesystem(path)
- if result is None:
- raise ValueError
- except Exception:
- return jsonify([])
- for item in result['directories']:
- data.append({'name': item['name'], 'children': True, 'path': item['path']})
- return jsonify(data)
-
-
-class WebHooksPlex(Resource):
- @authenticate
- def post(self):
- json_webhook = request.form.get('payload')
- parsed_json_webhook = json.loads(json_webhook)
-
- event = parsed_json_webhook['event']
- if event not in ['media.play']:
- return '', 204
-
- media_type = parsed_json_webhook['Metadata']['type']
-
- if media_type == 'episode':
- season = parsed_json_webhook['Metadata']['parentIndex']
- episode = parsed_json_webhook['Metadata']['index']
- else:
- season = episode = None
-
- ids = []
- for item in parsed_json_webhook['Metadata']['Guid']:
- splitted_id = item['id'].split('://')
- if len(splitted_id) == 2:
- ids.append({splitted_id[0]: splitted_id[1]})
- if not ids:
- return '', 404
-
- if media_type == 'episode':
- try:
- episode_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0]
- r = requests.get('https://imdb.com/title/{}'.format(episode_imdb_id),
- headers={"User-Agent": os.environ["SZ_USER_AGENT"]})
- soup = bso(r.content, "html.parser")
- series_imdb_id = soup.find('a', {'class': re.compile(r'SeriesParentLink__ParentTextLink')})['href'].split('/')[2]
- except:
- return '', 404
- else:
- sonarrEpisodeId = TableEpisodes.select(TableEpisodes.sonarrEpisodeId) \
- .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \
- .where(TableShows.imdbId == series_imdb_id,
- TableEpisodes.season == season,
- TableEpisodes.episode == episode) \
- .dicts() \
- .get()
-
- if sonarrEpisodeId:
- episode_download_subtitles(no=sonarrEpisodeId['sonarrEpisodeId'], send_progress=True)
- else:
- try:
- movie_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0]
- except:
- return '', 404
- else:
- radarrId = TableMovies.select(TableMovies.radarrId)\
- .where(TableMovies.imdbId == movie_imdb_id)\
- .dicts()\
- .get()
- if radarrId:
- movies_download_subtitles(no=radarrId['radarrId'])
-
- return '', 200
-
-
-api.add_resource(Badges, '/badges')
-
-api.add_resource(Providers, '/providers')
-api.add_resource(ProviderMovies, '/providers/movies')
-api.add_resource(ProviderEpisodes, '/providers/episodes')
-
-api.add_resource(System, '/system')
-api.add_resource(Searches, "/system/searches")
-api.add_resource(SystemAccount, '/system/account')
-api.add_resource(SystemTasks, '/system/tasks')
-api.add_resource(SystemLogs, '/system/logs')
-api.add_resource(SystemStatus, '/system/status')
-api.add_resource(SystemHealth, '/system/health')
-api.add_resource(SystemReleases, '/system/releases')
-api.add_resource(SystemSettings, '/system/settings')
-api.add_resource(Languages, '/system/languages')
-api.add_resource(LanguagesProfiles, '/system/languages/profiles')
-api.add_resource(Notifications, '/system/notifications')
-
-api.add_resource(Subtitles, '/subtitles')
-api.add_resource(SubtitleNameInfo, '/subtitles/info')
-
-api.add_resource(Series, '/series')
-
-api.add_resource(Episodes, '/episodes')
-api.add_resource(EpisodesWanted, '/episodes/wanted')
-api.add_resource(EpisodesSubtitles, '/episodes/subtitles')
-api.add_resource(EpisodesHistory, '/episodes/history')
-api.add_resource(EpisodesBlacklist, '/episodes/blacklist')
-
-api.add_resource(Movies, '/movies')
-api.add_resource(MoviesWanted, '/movies/wanted')
-api.add_resource(MoviesSubtitles, '/movies/subtitles')
-api.add_resource(MoviesHistory, '/movies/history')
-api.add_resource(MoviesBlacklist, '/movies/blacklist')
-
-api.add_resource(HistoryStats, '/history/stats')
-
-api.add_resource(BrowseBazarrFS, '/files')
-api.add_resource(BrowseSonarrFS, '/files/sonarr')
-api.add_resource(BrowseRadarrFS, '/files/radarr')
-
-api.add_resource(WebHooksPlex, '/webhooks/plex')
diff --git a/bazarr/api/__init__.py b/bazarr/api/__init__.py
new file mode 100644
index 000000000..85d075435
--- /dev/null
+++ b/bazarr/api/__init__.py
@@ -0,0 +1,25 @@
+# coding=utf-8
+
+from .badges import api_bp_badges
+from .system import api_bp_system
+from .series import api_bp_series
+from .episodes import api_bp_episodes
+from .providers import api_bp_providers
+from .subtitles import api_bp_subtitles
+from .webhooks import api_bp_webhooks
+from .history import api_bp_history
+from .files import api_bp_files
+from .movies import api_bp_movies
+
+api_bp_list = [
+ api_bp_badges,
+ api_bp_system,
+ api_bp_series,
+ api_bp_episodes,
+ api_bp_providers,
+ api_bp_subtitles,
+ api_bp_webhooks,
+ api_bp_history,
+ api_bp_files,
+ api_bp_movies
+]
diff --git a/bazarr/api/badges/__init__.py b/bazarr/api/badges/__init__.py
new file mode 100644
index 000000000..e5254c9b9
--- /dev/null
+++ b/bazarr/api/badges/__init__.py
@@ -0,0 +1,12 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .badges import Badges
+
+
+api_bp_badges = Blueprint('api_badges', __name__)
+api = Api(api_bp_badges)
+
+api.add_resource(Badges, '/badges')
diff --git a/bazarr/api/badges/badges.py b/bazarr/api/badges/badges.py
new file mode 100644
index 000000000..e9d6561f3
--- /dev/null
+++ b/bazarr/api/badges/badges.py
@@ -0,0 +1,47 @@
+# coding=utf-8
+
+from flask import jsonify
+from flask_restful import Resource
+
+import operator
+from functools import reduce
+
+from database import get_exclusion_clause, TableEpisodes, TableShows, TableMovies
+from get_providers import get_throttled_providers
+from utils import get_health_issues
+
+from ..utils import authenticate
+
+
+class Badges(Resource):
+ @authenticate
+ def get(self):
+ episodes_conditions = [(TableEpisodes.missing_subtitles is not None),
+ (TableEpisodes.missing_subtitles != '[]')]
+ episodes_conditions += get_exclusion_clause('series')
+ missing_episodes = TableEpisodes.select(TableShows.tags,
+ TableShows.seriesType,
+ TableEpisodes.monitored)\
+ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
+ .where(reduce(operator.and_, episodes_conditions))\
+ .count()
+
+ movies_conditions = [(TableMovies.missing_subtitles is not None),
+ (TableMovies.missing_subtitles != '[]')]
+ movies_conditions += get_exclusion_clause('movie')
+ missing_movies = TableMovies.select(TableMovies.tags,
+ TableMovies.monitored)\
+ .where(reduce(operator.and_, movies_conditions))\
+ .count()
+
+ throttled_providers = len(get_throttled_providers())
+
+ health_issues = len(get_health_issues())
+
+ result = {
+ "episodes": missing_episodes,
+ "movies": missing_movies,
+ "providers": throttled_providers,
+ "status": health_issues
+ }
+ return jsonify(result)
diff --git a/bazarr/api/episodes/__init__.py b/bazarr/api/episodes/__init__.py
new file mode 100644
index 000000000..2a5680ae7
--- /dev/null
+++ b/bazarr/api/episodes/__init__.py
@@ -0,0 +1,20 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .episodes import Episodes
+from .episodes_subtitles import EpisodesSubtitles
+from .history import EpisodesHistory
+from .wanted import EpisodesWanted
+from .blacklist import EpisodesBlacklist
+
+
+api_bp_episodes = Blueprint('api_episodes', __name__)
+api = Api(api_bp_episodes)
+
+api.add_resource(Episodes, '/episodes')
+api.add_resource(EpisodesWanted, '/episodes/wanted')
+api.add_resource(EpisodesSubtitles, '/episodes/subtitles')
+api.add_resource(EpisodesHistory, '/episodes/history')
+api.add_resource(EpisodesBlacklist, '/episodes/blacklist')
diff --git a/bazarr/api/episodes/blacklist.py b/bazarr/api/episodes/blacklist.py
new file mode 100644
index 000000000..800ad4ed8
--- /dev/null
+++ b/bazarr/api/episodes/blacklist.py
@@ -0,0 +1,92 @@
+# coding=utf-8
+
+import datetime
+import pretty
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from database import TableEpisodes, TableShows, TableBlacklist
+from ..utils import authenticate, postprocessEpisode
+from utils import blacklist_log, delete_subtitles, blacklist_delete_all, blacklist_delete
+from helper import path_mappings
+from get_subtitle import episode_download_subtitles
+from event_handler import event_stream
+
+
+# GET: get blacklist
+# POST: add blacklist
+# DELETE: remove blacklist
+class EpisodesBlacklist(Resource):
+ @authenticate
+ def get(self):
+ start = request.args.get('start') or 0
+ length = request.args.get('length') or -1
+
+ data = TableBlacklist.select(TableShows.title.alias('seriesTitle'),
+ TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
+ TableEpisodes.title.alias('episodeTitle'),
+ TableEpisodes.sonarrSeriesId,
+ TableBlacklist.provider,
+ TableBlacklist.subs_id,
+ TableBlacklist.language,
+ TableBlacklist.timestamp)\
+ .join(TableEpisodes, on=(TableBlacklist.sonarr_episode_id == TableEpisodes.sonarrEpisodeId))\
+ .join(TableShows, on=(TableBlacklist.sonarr_series_id == TableShows.sonarrSeriesId))\
+ .order_by(TableBlacklist.timestamp.desc())\
+ .limit(length)\
+ .offset(start)\
+ .dicts()
+ data = list(data)
+
+ for item in data:
+ # Make timestamp pretty
+ item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
+ item.update({'timestamp': pretty.date(datetime.datetime.fromtimestamp(item['timestamp']))})
+
+ postprocessEpisode(item)
+
+ return jsonify(data=data)
+
+ @authenticate
+ def post(self):
+ sonarr_series_id = int(request.args.get('seriesid'))
+ sonarr_episode_id = int(request.args.get('episodeid'))
+ provider = request.form.get('provider')
+ subs_id = request.form.get('subs_id')
+ language = request.form.get('language')
+
+ episodeInfo = TableEpisodes.select(TableEpisodes.path)\
+ .where(TableEpisodes.sonarrEpisodeId == sonarr_episode_id)\
+ .dicts()\
+ .get()
+
+ media_path = episodeInfo['path']
+ subtitles_path = request.form.get('subtitles_path')
+
+ blacklist_log(sonarr_series_id=sonarr_series_id,
+ sonarr_episode_id=sonarr_episode_id,
+ provider=provider,
+ subs_id=subs_id,
+ language=language)
+ delete_subtitles(media_type='series',
+ language=language,
+ forced=False,
+ hi=False,
+ media_path=path_mappings.path_replace(media_path),
+ subtitles_path=subtitles_path,
+ sonarr_series_id=sonarr_series_id,
+ sonarr_episode_id=sonarr_episode_id)
+ episode_download_subtitles(sonarr_episode_id)
+ event_stream(type='episode-history')
+ return '', 200
+
+ @authenticate
+ def delete(self):
+ if request.args.get("all") == "true":
+ blacklist_delete_all()
+ else:
+ provider = request.form.get('provider')
+ subs_id = request.form.get('subs_id')
+ blacklist_delete(provider=provider, subs_id=subs_id)
+ return '', 204
diff --git a/bazarr/api/episodes/episodes.py b/bazarr/api/episodes/episodes.py
new file mode 100644
index 000000000..1ce718c48
--- /dev/null
+++ b/bazarr/api/episodes/episodes.py
@@ -0,0 +1,30 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from database import TableEpisodes
+from ..utils import authenticate, postprocessEpisode
+
+
+class Episodes(Resource):
+ @authenticate
+ def get(self):
+ seriesId = request.args.getlist('seriesid[]')
+ episodeId = request.args.getlist('episodeid[]')
+
+ if len(episodeId) > 0:
+ result = TableEpisodes.select().where(TableEpisodes.sonarrEpisodeId.in_(episodeId)).dicts()
+ elif len(seriesId) > 0:
+ result = TableEpisodes.select()\
+ .where(TableEpisodes.sonarrSeriesId.in_(seriesId))\
+ .order_by(TableEpisodes.season.desc(), TableEpisodes.episode.desc())\
+ .dicts()
+ else:
+ return "Series or Episode ID not provided", 400
+
+ result = list(result)
+ for item in result:
+ postprocessEpisode(item)
+
+ return jsonify(data=result)
diff --git a/bazarr/api/episodes/episodes_subtitles.py b/bazarr/api/episodes/episodes_subtitles.py
new file mode 100644
index 000000000..70f59857c
--- /dev/null
+++ b/bazarr/api/episodes/episodes_subtitles.py
@@ -0,0 +1,178 @@
+# coding=utf-8
+
+import os
+
+from flask import request
+from flask_restful import Resource
+from subliminal_patch.core import SUBTITLE_EXTENSIONS
+
+from database import TableEpisodes, get_audio_profile_languages, get_profile_id
+from ..utils import authenticate
+from helper import path_mappings
+from get_providers import get_providers, get_providers_auth
+from get_subtitle import download_subtitle, manual_upload_subtitle
+from utils import history_log, delete_subtitles
+from notifier import send_notifications
+from list_subtitles import store_subtitles
+from event_handler import event_stream
+from config import settings
+
+
+# PATCH: Download Subtitles
+# POST: Upload Subtitles
+# DELETE: Delete Subtitles
+class EpisodesSubtitles(Resource):
+ @authenticate
+ def patch(self):
+ sonarrSeriesId = request.args.get('seriesid')
+ sonarrEpisodeId = request.args.get('episodeid')
+ episodeInfo = TableEpisodes.select(TableEpisodes.title,
+ TableEpisodes.path,
+ TableEpisodes.scene_name,
+ TableEpisodes.audio_language)\
+ .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
+ .dicts()\
+ .get()
+
+ title = episodeInfo['title']
+ episodePath = path_mappings.path_replace(episodeInfo['path'])
+ sceneName = episodeInfo['scene_name']
+ audio_language = episodeInfo['audio_language']
+ if sceneName is None: sceneName = "None"
+
+ language = request.form.get('language')
+ hi = request.form.get('hi').capitalize()
+ forced = request.form.get('forced').capitalize()
+
+ providers_list = get_providers()
+ providers_auth = get_providers_auth()
+
+ audio_language_list = get_audio_profile_languages(episode_id=sonarrEpisodeId)
+ if len(audio_language_list) > 0:
+ audio_language = audio_language_list[0]['name']
+ else:
+ audio_language = None
+
+ try:
+ result = download_subtitle(episodePath, language, audio_language, hi, forced, providers_list,
+ providers_auth, sceneName, title, 'series',
+ profile_id=get_profile_id(episode_id=sonarrEpisodeId))
+ if result is not None:
+ message = result[0]
+ path = result[1]
+ forced = result[5]
+ if result[8]:
+ language_code = result[2] + ":hi"
+ elif forced:
+ language_code = result[2] + ":forced"
+ else:
+ language_code = result[2]
+ provider = result[3]
+ score = result[4]
+ subs_id = result[6]
+ subs_path = result[7]
+ history_log(1, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score, subs_id,
+ subs_path)
+ send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
+ store_subtitles(path, episodePath)
+ else:
+ event_stream(type='episode', payload=sonarrEpisodeId)
+
+ except OSError:
+ pass
+
+ return '', 204
+
+ @authenticate
+ def post(self):
+ sonarrSeriesId = request.args.get('seriesid')
+ sonarrEpisodeId = request.args.get('episodeid')
+ episodeInfo = TableEpisodes.select(TableEpisodes.title,
+ TableEpisodes.path,
+ TableEpisodes.scene_name,
+ TableEpisodes.audio_language)\
+ .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
+ .dicts()\
+ .get()
+
+ title = episodeInfo['title']
+ episodePath = path_mappings.path_replace(episodeInfo['path'])
+ sceneName = episodeInfo['scene_name']
+ audio_language = episodeInfo['audio_language']
+ if sceneName is None: sceneName = "None"
+
+ language = request.form.get('language')
+ forced = True if request.form.get('forced') == 'true' else False
+ hi = True if request.form.get('hi') == 'true' else False
+ subFile = request.files.get('file')
+
+ _, ext = os.path.splitext(subFile.filename)
+
+ if ext not in SUBTITLE_EXTENSIONS:
+ raise ValueError('A subtitle of an invalid format was uploaded.')
+
+ try:
+ result = manual_upload_subtitle(path=episodePath,
+ language=language,
+ forced=forced,
+ hi=hi,
+ title=title,
+ scene_name=sceneName,
+ media_type='series',
+ subtitle=subFile,
+ audio_language=audio_language)
+
+ if result is not None:
+ message = result[0]
+ path = result[1]
+ subs_path = result[2]
+ if hi:
+ language_code = language + ":hi"
+ elif forced:
+ language_code = language + ":forced"
+ else:
+ language_code = language
+ provider = "manual"
+ score = 360
+ history_log(4, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score,
+ subtitles_path=subs_path)
+ if not settings.general.getboolean('dont_notify_manual_actions'):
+ send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
+ store_subtitles(path, episodePath)
+
+ except OSError:
+ pass
+
+ return '', 204
+
+ @authenticate
+ def delete(self):
+ sonarrSeriesId = request.args.get('seriesid')
+ sonarrEpisodeId = request.args.get('episodeid')
+ episodeInfo = TableEpisodes.select(TableEpisodes.title,
+ TableEpisodes.path,
+ TableEpisodes.scene_name,
+ TableEpisodes.audio_language)\
+ .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
+ .dicts()\
+ .get()
+
+ episodePath = path_mappings.path_replace(episodeInfo['path'])
+
+ language = request.form.get('language')
+ forced = request.form.get('forced')
+ hi = request.form.get('hi')
+ subtitlesPath = request.form.get('path')
+
+ subtitlesPath = path_mappings.path_replace_reverse(subtitlesPath)
+
+ delete_subtitles(media_type='series',
+ language=language,
+ forced=forced,
+ hi=hi,
+ media_path=episodePath,
+ subtitles_path=subtitlesPath,
+ sonarr_series_id=sonarrSeriesId,
+ sonarr_episode_id=sonarrEpisodeId)
+
+ return '', 204
diff --git a/bazarr/api/episodes/history.py b/bazarr/api/episodes/history.py
new file mode 100644
index 000000000..c3b4cab7c
--- /dev/null
+++ b/bazarr/api/episodes/history.py
@@ -0,0 +1,133 @@
+# coding=utf-8
+
+import datetime
+import os
+import operator
+import pretty
+
+from flask import request, jsonify
+from flask_restful import Resource
+from functools import reduce
+from peewee import fn
+from datetime import timedelta
+
+from database import get_exclusion_clause, TableEpisodes, TableShows, TableHistory, TableBlacklist
+from ..utils import authenticate, postprocessEpisode
+from config import settings
+from helper import path_mappings
+
+
+class EpisodesHistory(Resource):
+ @authenticate
+ def get(self):
+ start = request.args.get('start') or 0
+ length = request.args.get('length') or -1
+ episodeid = request.args.get('episodeid')
+
+ upgradable_episodes_not_perfect = []
+ if settings.general.getboolean('upgrade_subs'):
+ days_to_upgrade_subs = settings.general.days_to_upgrade_subs
+ minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
+ datetime.datetime(1970, 1, 1)).total_seconds()
+
+ if settings.general.getboolean('upgrade_manual'):
+ query_actions = [1, 2, 3, 6]
+ else:
+ query_actions = [1, 3]
+
+ upgradable_episodes_conditions = [(TableHistory.action.in_(query_actions)),
+ (TableHistory.timestamp > minimum_timestamp),
+ (TableHistory.score is not None)]
+ upgradable_episodes_conditions += get_exclusion_clause('series')
+ upgradable_episodes = TableHistory.select(TableHistory.video_path,
+ fn.MAX(TableHistory.timestamp).alias('timestamp'),
+ TableHistory.score,
+ TableShows.tags,
+ TableEpisodes.monitored,
+ TableShows.seriesType)\
+ .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
+ .join(TableShows, on=(TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId))\
+ .where(reduce(operator.and_, upgradable_episodes_conditions))\
+ .group_by(TableHistory.video_path)\
+ .dicts()
+ upgradable_episodes = list(upgradable_episodes)
+ for upgradable_episode in upgradable_episodes:
+ if upgradable_episode['timestamp'] > minimum_timestamp:
+ try:
+ int(upgradable_episode['score'])
+ except ValueError:
+ pass
+ else:
+ if int(upgradable_episode['score']) < 360:
+ upgradable_episodes_not_perfect.append(upgradable_episode)
+
+ query_conditions = [(TableEpisodes.title is not None)]
+ if episodeid:
+ query_conditions.append((TableEpisodes.sonarrEpisodeId == episodeid))
+ query_condition = reduce(operator.and_, query_conditions)
+ episode_history = TableHistory.select(TableHistory.id,
+ TableShows.title.alias('seriesTitle'),
+ TableEpisodes.monitored,
+ TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
+ TableEpisodes.title.alias('episodeTitle'),
+ TableHistory.timestamp,
+ TableHistory.subs_id,
+ TableHistory.description,
+ TableHistory.sonarrSeriesId,
+ TableEpisodes.path,
+ TableHistory.language,
+ TableHistory.score,
+ TableShows.tags,
+ TableHistory.action,
+ TableHistory.subtitles_path,
+ TableHistory.sonarrEpisodeId,
+ TableHistory.provider,
+ TableShows.seriesType)\
+ .join(TableShows, on=(TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId))\
+ .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
+ .where(query_condition)\
+ .order_by(TableHistory.timestamp.desc())\
+ .limit(length)\
+ .offset(start)\
+ .dicts()
+ episode_history = list(episode_history)
+
+ blacklist_db = TableBlacklist.select(TableBlacklist.provider, TableBlacklist.subs_id).dicts()
+ blacklist_db = list(blacklist_db)
+
+ for item in episode_history:
+ # Mark episode as upgradable or not
+ item.update({"upgradable": False})
+ if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score']),
+ "tags": str(item['tags']), "monitored": str(item['monitored']),
+ "seriesType": str(item['seriesType'])} in upgradable_episodes_not_perfect:
+ if os.path.isfile(path_mappings.path_replace(item['subtitles_path'])):
+ item.update({"upgradable": True})
+
+ del item['path']
+
+ postprocessEpisode(item)
+
+ if item['score']:
+ item['score'] = str(round((int(item['score']) * 100 / 360), 2)) + "%"
+
+ # Make timestamp pretty
+ if item['timestamp']:
+ item["raw_timestamp"] = int(item['timestamp'])
+ item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
+ item['timestamp'] = pretty.date(item["raw_timestamp"])
+
+ # Check if subtitles is blacklisted
+ item.update({"blacklisted": False})
+ if item['action'] not in [0, 4, 5]:
+ for blacklisted_item in blacklist_db:
+ if blacklisted_item['provider'] == item['provider'] and \
+ blacklisted_item['subs_id'] == item['subs_id']:
+ item.update({"blacklisted": True})
+ break
+
+ count = TableHistory.select()\
+ .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
+ .where(TableEpisodes.title is not None).count()
+
+ return jsonify(data=episode_history, total=count)
diff --git a/bazarr/api/episodes/wanted.py b/bazarr/api/episodes/wanted.py
new file mode 100644
index 000000000..3634a69b3
--- /dev/null
+++ b/bazarr/api/episodes/wanted.py
@@ -0,0 +1,74 @@
+# coding=utf-8
+
+import operator
+
+from flask import request, jsonify
+from flask_restful import Resource
+from functools import reduce
+
+from database import get_exclusion_clause, TableEpisodes, TableShows
+from ..utils import authenticate, postprocessEpisode
+
+
+# GET: Get Wanted Episodes
+class EpisodesWanted(Resource):
+ @authenticate
+ def get(self):
+ episodeid = request.args.getlist('episodeid[]')
+
+ wanted_conditions = [(TableEpisodes.missing_subtitles != '[]')]
+ if len(episodeid) > 0:
+ wanted_conditions.append((TableEpisodes.sonarrEpisodeId in episodeid))
+ wanted_conditions += get_exclusion_clause('series')
+ wanted_condition = reduce(operator.and_, wanted_conditions)
+
+ if len(episodeid) > 0:
+ data = TableEpisodes.select(TableShows.title.alias('seriesTitle'),
+ TableEpisodes.monitored,
+ TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
+ TableEpisodes.title.alias('episodeTitle'),
+ TableEpisodes.missing_subtitles,
+ TableEpisodes.sonarrSeriesId,
+ TableEpisodes.sonarrEpisodeId,
+ TableEpisodes.scene_name.alias('sceneName'),
+ TableShows.tags,
+ TableEpisodes.failedAttempts,
+ TableShows.seriesType)\
+ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
+ .where(wanted_condition)\
+ .dicts()
+ else:
+ start = request.args.get('start') or 0
+ length = request.args.get('length') or -1
+ data = TableEpisodes.select(TableShows.title.alias('seriesTitle'),
+ TableEpisodes.monitored,
+ TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
+ TableEpisodes.title.alias('episodeTitle'),
+ TableEpisodes.missing_subtitles,
+ TableEpisodes.sonarrSeriesId,
+ TableEpisodes.sonarrEpisodeId,
+ TableEpisodes.scene_name.alias('sceneName'),
+ TableShows.tags,
+ TableEpisodes.failedAttempts,
+ TableShows.seriesType)\
+ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
+ .where(wanted_condition)\
+ .order_by(TableEpisodes.rowid.desc())\
+ .limit(length)\
+ .offset(start)\
+ .dicts()
+ data = list(data)
+
+ for item in data:
+ postprocessEpisode(item)
+
+ count_conditions = [(TableEpisodes.missing_subtitles != '[]')]
+ count_conditions += get_exclusion_clause('series')
+ count = TableEpisodes.select(TableShows.tags,
+ TableShows.seriesType,
+ TableEpisodes.monitored)\
+ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
+ .where(reduce(operator.and_, count_conditions))\
+ .count()
+
+ return jsonify(data=data, total=count)
diff --git a/bazarr/api/files/__init__.py b/bazarr/api/files/__init__.py
new file mode 100644
index 000000000..7c78565c9
--- /dev/null
+++ b/bazarr/api/files/__init__.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .files import BrowseBazarrFS
+from .files_sonarr import BrowseSonarrFS
+from .files_radarr import BrowseRadarrFS
+
+
+api_bp_files = Blueprint('api_files', __name__)
+api = Api(api_bp_files)
+
+api.add_resource(BrowseBazarrFS, '/files')
+api.add_resource(BrowseSonarrFS, '/files/sonarr')
+api.add_resource(BrowseRadarrFS, '/files/radarr')
diff --git a/bazarr/api/files/files.py b/bazarr/api/files/files.py
new file mode 100644
index 000000000..bcec93b75
--- /dev/null
+++ b/bazarr/api/files/files.py
@@ -0,0 +1,24 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from filesystem import browse_bazarr_filesystem
+
+from ..utils import authenticate
+
+
+class BrowseBazarrFS(Resource):
+ @authenticate
+ def get(self):
+ path = request.args.get('path') or ''
+ data = []
+ try:
+ result = browse_bazarr_filesystem(path)
+ if result is None:
+ raise ValueError
+ except Exception:
+ return jsonify([])
+ for item in result['directories']:
+ data.append({'name': item['name'], 'children': True, 'path': item['path']})
+ return jsonify(data)
diff --git a/bazarr/api/files/files_radarr.py b/bazarr/api/files/files_radarr.py
new file mode 100644
index 000000000..156d73d33
--- /dev/null
+++ b/bazarr/api/files/files_radarr.py
@@ -0,0 +1,24 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from filesystem import browse_radarr_filesystem
+
+from ..utils import authenticate
+
+
+class BrowseRadarrFS(Resource):
+ @authenticate
+ def get(self):
+ path = request.args.get('path') or ''
+ data = []
+ try:
+ result = browse_radarr_filesystem(path)
+ if result is None:
+ raise ValueError
+ except Exception:
+ return jsonify([])
+ for item in result['directories']:
+ data.append({'name': item['name'], 'children': True, 'path': item['path']})
+ return jsonify(data)
diff --git a/bazarr/api/files/files_sonarr.py b/bazarr/api/files/files_sonarr.py
new file mode 100644
index 000000000..0007157dc
--- /dev/null
+++ b/bazarr/api/files/files_sonarr.py
@@ -0,0 +1,24 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from filesystem import browse_sonarr_filesystem
+
+from ..utils import authenticate
+
+
+class BrowseSonarrFS(Resource):
+ @authenticate
+ def get(self):
+ path = request.args.get('path') or ''
+ data = []
+ try:
+ result = browse_sonarr_filesystem(path)
+ if result is None:
+ raise ValueError
+ except Exception:
+ return jsonify([])
+ for item in result['directories']:
+ data.append({'name': item['name'], 'children': True, 'path': item['path']})
+ return jsonify(data)
diff --git a/bazarr/api/history/__init__.py b/bazarr/api/history/__init__.py
new file mode 100644
index 000000000..2783a1233
--- /dev/null
+++ b/bazarr/api/history/__init__.py
@@ -0,0 +1,12 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .stats import HistoryStats
+
+
+api_bp_history = Blueprint('api_history', __name__)
+api = Api(api_bp_history)
+
+api.add_resource(HistoryStats, '/history/stats')
diff --git a/bazarr/api/history/stats.py b/bazarr/api/history/stats.py
new file mode 100644
index 000000000..b9651399d
--- /dev/null
+++ b/bazarr/api/history/stats.py
@@ -0,0 +1,85 @@
+# coding=utf-8
+
+import time
+import datetime
+import operator
+
+from dateutil import rrule
+from flask import request, jsonify
+from flask_restful import Resource
+from functools import reduce
+from peewee import fn
+
+from database import TableHistory, TableHistoryMovie
+
+from ..utils import authenticate
+
+
+class HistoryStats(Resource):
+ @authenticate
+ def get(self):
+ timeframe = request.args.get('timeframe') or 'month'
+ action = request.args.get('action') or 'All'
+ provider = request.args.get('provider') or 'All'
+ language = request.args.get('language') or 'All'
+
+ # timeframe must be in ['week', 'month', 'trimester', 'year']
+ if timeframe == 'year':
+ delay = 364 * 24 * 60 * 60
+ elif timeframe == 'trimester':
+ delay = 90 * 24 * 60 * 60
+ elif timeframe == 'month':
+ delay = 30 * 24 * 60 * 60
+ elif timeframe == 'week':
+ delay = 6 * 24 * 60 * 60
+
+ now = time.time()
+ past = now - delay
+
+ history_where_clauses = [(TableHistory.timestamp.between(past, now))]
+ history_where_clauses_movie = [(TableHistoryMovie.timestamp.between(past, now))]
+
+ if action != 'All':
+ history_where_clauses.append((TableHistory.action == action))
+ history_where_clauses_movie.append((TableHistoryMovie.action == action))
+ else:
+ history_where_clauses.append((TableHistory.action.in_([1, 2, 3])))
+ history_where_clauses_movie.append((TableHistoryMovie.action.in_([1, 2, 3])))
+
+ if provider != 'All':
+ history_where_clauses.append((TableHistory.provider == provider))
+ history_where_clauses_movie.append((TableHistoryMovie.provider == provider))
+
+ if language != 'All':
+ history_where_clauses.append((TableHistory.language == language))
+ history_where_clauses_movie.append((TableHistoryMovie.language == language))
+
+ history_where_clause = reduce(operator.and_, history_where_clauses)
+ history_where_clause_movie = reduce(operator.and_, history_where_clauses_movie)
+
+ data_series = TableHistory.select(fn.strftime('%Y-%m-%d', TableHistory.timestamp, 'unixepoch').alias('date'),
+ fn.COUNT(TableHistory.id).alias('count'))\
+ .where(history_where_clause) \
+ .group_by(fn.strftime('%Y-%m-%d', TableHistory.timestamp, 'unixepoch'))\
+ .dicts()
+ data_series = list(data_series)
+
+ data_movies = TableHistoryMovie.select(fn.strftime('%Y-%m-%d', TableHistoryMovie.timestamp, 'unixepoch').alias('date'),
+ fn.COUNT(TableHistoryMovie.id).alias('count')) \
+ .where(history_where_clause_movie) \
+ .group_by(fn.strftime('%Y-%m-%d', TableHistoryMovie.timestamp, 'unixepoch')) \
+ .dicts()
+ data_movies = list(data_movies)
+
+ for dt in rrule.rrule(rrule.DAILY,
+ dtstart=datetime.datetime.now() - datetime.timedelta(seconds=delay),
+ until=datetime.datetime.now()):
+ if not any(d['date'] == dt.strftime('%Y-%m-%d') for d in data_series):
+ data_series.append({'date': dt.strftime('%Y-%m-%d'), 'count': 0})
+ if not any(d['date'] == dt.strftime('%Y-%m-%d') for d in data_movies):
+ data_movies.append({'date': dt.strftime('%Y-%m-%d'), 'count': 0})
+
+ sorted_data_series = sorted(data_series, key=lambda i: i['date'])
+ sorted_data_movies = sorted(data_movies, key=lambda i: i['date'])
+
+ return jsonify(series=sorted_data_series, movies=sorted_data_movies)
diff --git a/bazarr/api/movies/__init__.py b/bazarr/api/movies/__init__.py
new file mode 100644
index 000000000..eb691f529
--- /dev/null
+++ b/bazarr/api/movies/__init__.py
@@ -0,0 +1,20 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .movies import Movies
+from .movies_subtitles import MoviesSubtitles
+from .history import MoviesHistory
+from .wanted import MoviesWanted
+from .blacklist import MoviesBlacklist
+
+
+api_bp_movies = Blueprint('api_movies', __name__)
+api = Api(api_bp_movies)
+
+api.add_resource(Movies, '/movies')
+api.add_resource(MoviesWanted, '/movies/wanted')
+api.add_resource(MoviesSubtitles, '/movies/subtitles')
+api.add_resource(MoviesHistory, '/movies/history')
+api.add_resource(MoviesBlacklist, '/movies/blacklist')
diff --git a/bazarr/api/movies/blacklist.py b/bazarr/api/movies/blacklist.py
new file mode 100644
index 000000000..cda24f348
--- /dev/null
+++ b/bazarr/api/movies/blacklist.py
@@ -0,0 +1,86 @@
+# coding=utf-8
+
+import datetime
+import pretty
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from database import TableMovies, TableBlacklistMovie
+from ..utils import authenticate, postprocessMovie
+from utils import blacklist_log_movie, delete_subtitles, blacklist_delete_all_movie, blacklist_delete_movie
+from helper import path_mappings
+from get_subtitle import movies_download_subtitles
+from event_handler import event_stream
+
+
+# GET: get blacklist
+# POST: add blacklist
+# DELETE: remove blacklist
+class MoviesBlacklist(Resource):
+ @authenticate
+ def get(self):
+ start = request.args.get('start') or 0
+ length = request.args.get('length') or -1
+
+ data = TableBlacklistMovie.select(TableMovies.title,
+ TableMovies.radarrId,
+ TableBlacklistMovie.provider,
+ TableBlacklistMovie.subs_id,
+ TableBlacklistMovie.language,
+ TableBlacklistMovie.timestamp)\
+ .join(TableMovies, on=(TableBlacklistMovie.radarr_id == TableMovies.radarrId))\
+ .order_by(TableBlacklistMovie.timestamp.desc())\
+ .limit(length)\
+ .offset(start)\
+ .dicts()
+ data = list(data)
+
+ for item in data:
+ postprocessMovie(item)
+
+ # Make timestamp pretty
+ item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
+ item.update({'timestamp': pretty.date(datetime.datetime.fromtimestamp(item['timestamp']))})
+
+ return jsonify(data=data)
+
+ @authenticate
+ def post(self):
+ radarr_id = int(request.args.get('radarrid'))
+ provider = request.form.get('provider')
+ subs_id = request.form.get('subs_id')
+ language = request.form.get('language')
+ # TODO
+ forced = False
+ hi = False
+
+ data = TableMovies.select(TableMovies.path).where(TableMovies.radarrId == radarr_id).dicts().get()
+
+ media_path = data['path']
+ subtitles_path = request.form.get('subtitles_path')
+
+ blacklist_log_movie(radarr_id=radarr_id,
+ provider=provider,
+ subs_id=subs_id,
+ language=language)
+ delete_subtitles(media_type='movie',
+ language=language,
+ forced=forced,
+ hi=hi,
+ media_path=path_mappings.path_replace_movie(media_path),
+ subtitles_path=subtitles_path,
+ radarr_id=radarr_id)
+ movies_download_subtitles(radarr_id)
+ event_stream(type='movie-history')
+ return '', 200
+
+ @authenticate
+ def delete(self):
+ if request.args.get("all") == "true":
+ blacklist_delete_all_movie()
+ else:
+ provider = request.form.get('provider')
+ subs_id = request.form.get('subs_id')
+ blacklist_delete_movie(provider=provider, subs_id=subs_id)
+ return '', 200
diff --git a/bazarr/api/movies/history.py b/bazarr/api/movies/history.py
new file mode 100644
index 000000000..13e3c6d88
--- /dev/null
+++ b/bazarr/api/movies/history.py
@@ -0,0 +1,129 @@
+# coding=utf-8
+
+import datetime
+import os
+import operator
+import pretty
+
+from flask import request, jsonify
+from flask_restful import Resource
+from functools import reduce
+from peewee import fn
+from datetime import timedelta
+
+from database import get_exclusion_clause, TableMovies, TableHistoryMovie, TableBlacklistMovie
+from ..utils import authenticate, postprocessMovie
+from config import settings
+from helper import path_mappings
+
+
+class MoviesHistory(Resource):
+ @authenticate
+ def get(self):
+ start = request.args.get('start') or 0
+ length = request.args.get('length') or -1
+ radarrid = request.args.get('radarrid')
+
+ upgradable_movies = []
+ upgradable_movies_not_perfect = []
+ if settings.general.getboolean('upgrade_subs'):
+ days_to_upgrade_subs = settings.general.days_to_upgrade_subs
+ minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
+ datetime.datetime(1970, 1, 1)).total_seconds()
+
+ if settings.general.getboolean('upgrade_manual'):
+ query_actions = [1, 2, 3, 6]
+ else:
+ query_actions = [1, 3]
+
+ upgradable_movies_conditions = [(TableHistoryMovie.action.in_(query_actions)),
+ (TableHistoryMovie.timestamp > minimum_timestamp),
+ (TableHistoryMovie.score is not None)]
+ upgradable_movies_conditions += get_exclusion_clause('movie')
+ upgradable_movies = TableHistoryMovie.select(TableHistoryMovie.video_path,
+ fn.MAX(TableHistoryMovie.timestamp).alias('timestamp'),
+ TableHistoryMovie.score,
+ TableMovies.tags,
+ TableMovies.monitored)\
+ .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
+ .where(reduce(operator.and_, upgradable_movies_conditions))\
+ .group_by(TableHistoryMovie.video_path)\
+ .dicts()
+ upgradable_movies = list(upgradable_movies)
+
+ for upgradable_movie in upgradable_movies:
+ if upgradable_movie['timestamp'] > minimum_timestamp:
+ try:
+ int(upgradable_movie['score'])
+ except ValueError:
+ pass
+ else:
+ if int(upgradable_movie['score']) < 120:
+ upgradable_movies_not_perfect.append(upgradable_movie)
+
+ query_conditions = [(TableMovies.title is not None)]
+ if radarrid:
+ query_conditions.append((TableMovies.radarrId == radarrid))
+ query_condition = reduce(operator.and_, query_conditions)
+
+ movie_history = TableHistoryMovie.select(TableHistoryMovie.id,
+ TableHistoryMovie.action,
+ TableMovies.title,
+ TableHistoryMovie.timestamp,
+ TableHistoryMovie.description,
+ TableHistoryMovie.radarrId,
+ TableMovies.monitored,
+ TableHistoryMovie.video_path.alias('path'),
+ TableHistoryMovie.language,
+ TableMovies.tags,
+ TableHistoryMovie.score,
+ TableHistoryMovie.subs_id,
+ TableHistoryMovie.provider,
+ TableHistoryMovie.subtitles_path)\
+ .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
+ .where(query_condition)\
+ .order_by(TableHistoryMovie.timestamp.desc())\
+ .limit(length)\
+ .offset(start)\
+ .dicts()
+ movie_history = list(movie_history)
+
+ blacklist_db = TableBlacklistMovie.select(TableBlacklistMovie.provider, TableBlacklistMovie.subs_id).dicts()
+ blacklist_db = list(blacklist_db)
+
+ for item in movie_history:
+ # Mark movies as upgradable or not
+ item.update({"upgradable": False})
+ if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score']),
+ "tags": str(item['tags']), "monitored": str(item['monitored'])} in upgradable_movies_not_perfect:
+ if os.path.isfile(path_mappings.path_replace_movie(item['subtitles_path'])):
+ item.update({"upgradable": True})
+
+ del item['path']
+
+ postprocessMovie(item)
+
+ if item['score']:
+ item['score'] = str(round((int(item['score']) * 100 / 120), 2)) + "%"
+
+ # Make timestamp pretty
+ if item['timestamp']:
+ item["raw_timestamp"] = int(item['timestamp'])
+ item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
+ item['timestamp'] = pretty.date(item["raw_timestamp"])
+
+ # Check if subtitles is blacklisted
+ item.update({"blacklisted": False})
+ if item['action'] not in [0, 4, 5]:
+ for blacklisted_item in blacklist_db:
+ if blacklisted_item['provider'] == item['provider'] and blacklisted_item['subs_id'] == item[
+ 'subs_id']:
+ item.update({"blacklisted": True})
+ break
+
+ count = TableHistoryMovie.select()\
+ .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
+ .where(TableMovies.title is not None)\
+ .count()
+
+ return jsonify(data=movie_history, total=count)
diff --git a/bazarr/api/movies/movies.py b/bazarr/api/movies/movies.py
new file mode 100644
index 000000000..d088a71a5
--- /dev/null
+++ b/bazarr/api/movies/movies.py
@@ -0,0 +1,80 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from database import TableMovies
+from ..utils import authenticate, postprocessMovie, None_Keys
+from list_subtitles import list_missing_subtitles_movies, movies_scan_subtitles
+from event_handler import event_stream
+from get_subtitle import movies_download_subtitles, wanted_search_missing_subtitles_movies
+
+
+class Movies(Resource):
+ @authenticate
+ def get(self):
+ start = request.args.get('start') or 0
+ length = request.args.get('length') or -1
+ radarrId = request.args.getlist('radarrid[]')
+
+ count = TableMovies.select().count()
+
+ if len(radarrId) != 0:
+ result = TableMovies.select()\
+ .where(TableMovies.radarrId.in_(radarrId))\
+ .order_by(TableMovies.sortTitle)\
+ .dicts()
+ else:
+ result = TableMovies.select().order_by(TableMovies.sortTitle).limit(length).offset(start).dicts()
+ result = list(result)
+ for item in result:
+ postprocessMovie(item)
+
+ return jsonify(data=result, total=count)
+
+ @authenticate
+ def post(self):
+ radarrIdList = request.form.getlist('radarrid')
+ profileIdList = request.form.getlist('profileid')
+
+ for idx in range(len(radarrIdList)):
+ radarrId = radarrIdList[idx]
+ profileId = profileIdList[idx]
+
+ if profileId in None_Keys:
+ profileId = None
+ else:
+ try:
+ profileId = int(profileId)
+ except Exception:
+ return '', 400
+
+ TableMovies.update({
+ TableMovies.profileId: profileId
+ })\
+ .where(TableMovies.radarrId == radarrId)\
+ .execute()
+
+ list_missing_subtitles_movies(no=radarrId, send_event=False)
+
+ event_stream(type='movie', payload=radarrId)
+ event_stream(type='movie-wanted', payload=radarrId)
+ event_stream(type='badges')
+
+ return '', 204
+
+ @authenticate
+ def patch(self):
+ radarrid = request.form.get('radarrid')
+ action = request.form.get('action')
+ if action == "scan-disk":
+ movies_scan_subtitles(radarrid)
+ return '', 204
+ elif action == "search-missing":
+ movies_download_subtitles(radarrid)
+ return '', 204
+ elif action == "search-wanted":
+ wanted_search_missing_subtitles_movies()
+ return '', 204
+
+ return '', 400
diff --git a/bazarr/api/movies/movies_subtitles.py b/bazarr/api/movies/movies_subtitles.py
new file mode 100644
index 000000000..c4f1a1e2a
--- /dev/null
+++ b/bazarr/api/movies/movies_subtitles.py
@@ -0,0 +1,176 @@
+# coding=utf-8
+
+import os
+
+from flask import request
+from flask_restful import Resource
+from subliminal_patch.core import SUBTITLE_EXTENSIONS
+
+from database import TableMovies, get_audio_profile_languages, get_profile_id
+from ..utils import authenticate
+from helper import path_mappings
+from get_providers import get_providers, get_providers_auth
+from get_subtitle import download_subtitle, manual_upload_subtitle
+from utils import history_log_movie, delete_subtitles
+from notifier import send_notifications_movie
+from list_subtitles import store_subtitles_movie
+from event_handler import event_stream
+from config import settings
+
+
+# PATCH: Download Subtitles
+# POST: Upload Subtitles
+# DELETE: Delete Subtitles
+class MoviesSubtitles(Resource):
+ @authenticate
+ def patch(self):
+ # Download
+ radarrId = request.args.get('radarrid')
+
+ movieInfo = TableMovies.select(TableMovies.title,
+ TableMovies.path,
+ TableMovies.sceneName,
+ TableMovies.audio_language)\
+ .where(TableMovies.radarrId == radarrId)\
+ .dicts()\
+ .get()
+
+ moviePath = path_mappings.path_replace_movie(movieInfo['path'])
+ sceneName = movieInfo['sceneName']
+ if sceneName is None: sceneName = 'None'
+
+ title = movieInfo['title']
+ audio_language = movieInfo['audio_language']
+
+ language = request.form.get('language')
+ hi = request.form.get('hi').capitalize()
+ forced = request.form.get('forced').capitalize()
+
+ providers_list = get_providers()
+ providers_auth = get_providers_auth()
+
+ audio_language_list = get_audio_profile_languages(movie_id=radarrId)
+ if len(audio_language_list) > 0:
+ audio_language = audio_language_list[0]['name']
+ else:
+ audio_language = None
+
+ try:
+ result = download_subtitle(moviePath, language, audio_language, hi, forced, providers_list,
+ providers_auth, sceneName, title, 'movie',
+ profile_id=get_profile_id(movie_id=radarrId))
+ if result is not None:
+ message = result[0]
+ path = result[1]
+ forced = result[5]
+ if result[8]:
+ language_code = result[2] + ":hi"
+ elif forced:
+ language_code = result[2] + ":forced"
+ else:
+ language_code = result[2]
+ provider = result[3]
+ score = result[4]
+ subs_id = result[6]
+ subs_path = result[7]
+ history_log_movie(1, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
+ send_notifications_movie(radarrId, message)
+ store_subtitles_movie(path, moviePath)
+ else:
+ event_stream(type='movie', payload=radarrId)
+ except OSError:
+ pass
+
+ return '', 204
+
+ @authenticate
+ def post(self):
+ # Upload
+ # TODO: Support Multiply Upload
+ radarrId = request.args.get('radarrid')
+ movieInfo = TableMovies.select(TableMovies.title,
+ TableMovies.path,
+ TableMovies.sceneName,
+ TableMovies.audio_language) \
+ .where(TableMovies.radarrId == radarrId) \
+ .dicts() \
+ .get()
+
+ moviePath = path_mappings.path_replace_movie(movieInfo['path'])
+ sceneName = movieInfo['sceneName']
+ if sceneName is None: sceneName = 'None'
+
+ title = movieInfo['title']
+ audioLanguage = movieInfo['audio_language']
+
+ language = request.form.get('language')
+ forced = True if request.form.get('forced') == 'true' else False
+ hi = True if request.form.get('hi') == 'true' else False
+ subFile = request.files.get('file')
+
+ _, ext = os.path.splitext(subFile.filename)
+
+ if ext not in SUBTITLE_EXTENSIONS:
+ raise ValueError('A subtitle of an invalid format was uploaded.')
+
+ try:
+ result = manual_upload_subtitle(path=moviePath,
+ language=language,
+ forced=forced,
+ hi=hi,
+ title=title,
+ scene_name=sceneName,
+ media_type='movie',
+ subtitle=subFile,
+ audio_language=audioLanguage)
+
+ if result is not None:
+ message = result[0]
+ path = result[1]
+ subs_path = result[2]
+ if hi:
+ language_code = language + ":hi"
+ elif forced:
+ language_code = language + ":forced"
+ else:
+ language_code = language
+ provider = "manual"
+ score = 120
+ history_log_movie(4, radarrId, message, path, language_code, provider, score, subtitles_path=subs_path)
+ if not settings.general.getboolean('dont_notify_manual_actions'):
+ send_notifications_movie(radarrId, message)
+ store_subtitles_movie(path, moviePath)
+ except OSError:
+ pass
+
+ return '', 204
+
+ @authenticate
+ def delete(self):
+ # Delete
+ radarrId = request.args.get('radarrid')
+ movieInfo = TableMovies.select(TableMovies.path) \
+ .where(TableMovies.radarrId == radarrId) \
+ .dicts() \
+ .get()
+
+ moviePath = path_mappings.path_replace_movie(movieInfo['path'])
+
+ language = request.form.get('language')
+ forced = request.form.get('forced')
+ hi = request.form.get('hi')
+ subtitlesPath = request.form.get('path')
+
+ subtitlesPath = path_mappings.path_replace_reverse_movie(subtitlesPath)
+
+ result = delete_subtitles(media_type='movie',
+ language=language,
+ forced=forced,
+ hi=hi,
+ media_path=moviePath,
+ subtitles_path=subtitlesPath,
+ radarr_id=radarrId)
+ if result:
+ return '', 202
+ else:
+ return '', 204
diff --git a/bazarr/api/movies/wanted.py b/bazarr/api/movies/wanted.py
new file mode 100644
index 000000000..45511f0ab
--- /dev/null
+++ b/bazarr/api/movies/wanted.py
@@ -0,0 +1,62 @@
+# coding=utf-8
+
+import operator
+
+from flask import request, jsonify
+from flask_restful import Resource
+from functools import reduce
+
+from database import get_exclusion_clause, TableMovies
+from ..utils import authenticate, postprocessMovie
+
+
+# GET: Get Wanted Movies
+class MoviesWanted(Resource):
+ @authenticate
+ def get(self):
+ radarrid = request.args.getlist("radarrid[]")
+
+ wanted_conditions = [(TableMovies.missing_subtitles != '[]')]
+ if len(radarrid) > 0:
+ wanted_conditions.append((TableMovies.radarrId.in_(radarrid)))
+ wanted_conditions += get_exclusion_clause('movie')
+ wanted_condition = reduce(operator.and_, wanted_conditions)
+
+ if len(radarrid) > 0:
+ result = TableMovies.select(TableMovies.title,
+ TableMovies.missing_subtitles,
+ TableMovies.radarrId,
+ TableMovies.sceneName,
+ TableMovies.failedAttempts,
+ TableMovies.tags,
+ TableMovies.monitored)\
+ .where(wanted_condition)\
+ .dicts()
+ else:
+ start = request.args.get('start') or 0
+ length = request.args.get('length') or -1
+ result = TableMovies.select(TableMovies.title,
+ TableMovies.missing_subtitles,
+ TableMovies.radarrId,
+ TableMovies.sceneName,
+ TableMovies.failedAttempts,
+ TableMovies.tags,
+ TableMovies.monitored)\
+ .where(wanted_condition)\
+ .order_by(TableMovies.rowid.desc())\
+ .limit(length)\
+ .offset(start)\
+ .dicts()
+ result = list(result)
+
+ for item in result:
+ postprocessMovie(item)
+
+ count_conditions = [(TableMovies.missing_subtitles != '[]')]
+ count_conditions += get_exclusion_clause('movie')
+ count = TableMovies.select(TableMovies.monitored,
+ TableMovies.tags)\
+ .where(reduce(operator.and_, count_conditions))\
+ .count()
+
+ return jsonify(data=result, total=count)
diff --git a/bazarr/api/providers/__init__.py b/bazarr/api/providers/__init__.py
new file mode 100644
index 000000000..dc3793d70
--- /dev/null
+++ b/bazarr/api/providers/__init__.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .providers import Providers
+from .providers_episodes import ProviderEpisodes
+from .providers_movies import ProviderMovies
+
+
+api_bp_providers = Blueprint('api_providers', __name__)
+api = Api(api_bp_providers)
+
+api.add_resource(Providers, '/providers')
+api.add_resource(ProviderMovies, '/providers/movies')
+api.add_resource(ProviderEpisodes, '/providers/episodes')
diff --git a/bazarr/api/providers/providers.py b/bazarr/api/providers/providers.py
new file mode 100644
index 000000000..0bcfb45a7
--- /dev/null
+++ b/bazarr/api/providers/providers.py
@@ -0,0 +1,52 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+from operator import itemgetter
+
+from database import TableHistory, TableHistoryMovie
+from get_providers import list_throttled_providers, reset_throttled_providers
+from ..utils import authenticate, False_Keys
+
+
+class Providers(Resource):
+ @authenticate
+ def get(self):
+ history = request.args.get('history')
+ if history and history not in False_Keys:
+ providers = list(TableHistory.select(TableHistory.provider)
+ .where(TableHistory.provider != None and TableHistory.provider != "manual")
+ .dicts())
+ providers += list(TableHistoryMovie.select(TableHistoryMovie.provider)
+ .where(TableHistoryMovie.provider != None and TableHistoryMovie.provider != "manual")
+ .dicts())
+ providers_list = list(set([x['provider'] for x in providers]))
+ providers_dicts = []
+ for provider in providers_list:
+ providers_dicts.append({
+ 'name': provider,
+ 'status': 'History',
+ 'retry': '-'
+ })
+ return jsonify(data=sorted(providers_dicts, key=itemgetter('name')))
+
+ throttled_providers = list_throttled_providers()
+
+ providers = list()
+ for provider in throttled_providers:
+ providers.append({
+ "name": provider[0],
+ "status": provider[1] if provider[1] is not None else "Good",
+ "retry": provider[2] if provider[2] != "now" else "-"
+ })
+ return jsonify(data=providers)
+
+ @authenticate
+ def post(self):
+ action = request.form.get('action')
+
+ if action == 'reset':
+ reset_throttled_providers()
+ return '', 204
+
+ return '', 400
diff --git a/bazarr/api/providers/providers_episodes.py b/bazarr/api/providers/providers_episodes.py
new file mode 100644
index 000000000..283cc160d
--- /dev/null
+++ b/bazarr/api/providers/providers_episodes.py
@@ -0,0 +1,104 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from database import TableEpisodes, TableShows, get_audio_profile_languages, get_profile_id
+from helper import path_mappings
+from get_providers import get_providers, get_providers_auth
+from get_subtitle import manual_search, manual_download_subtitle
+from utils import history_log
+from config import settings
+from notifier import send_notifications
+from list_subtitles import store_subtitles
+
+from ..utils import authenticate
+
+
+class ProviderEpisodes(Resource):
+ @authenticate
+ def get(self):
+ # Manual Search
+ sonarrEpisodeId = request.args.get('episodeid')
+ episodeInfo = TableEpisodes.select(TableEpisodes.title,
+ TableEpisodes.path,
+ TableEpisodes.scene_name,
+ TableShows.profileId) \
+ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
+ .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId) \
+ .dicts() \
+ .get()
+
+ title = episodeInfo['title']
+ episodePath = path_mappings.path_replace(episodeInfo['path'])
+ sceneName = episodeInfo['scene_name']
+ profileId = episodeInfo['profileId']
+ if sceneName is None: sceneName = "None"
+
+ providers_list = get_providers()
+ providers_auth = get_providers_auth()
+
+ data = manual_search(episodePath, profileId, providers_list, providers_auth, sceneName, title,
+ 'series')
+ if not data:
+ data = []
+ return jsonify(data=data)
+
+ @authenticate
+ def post(self):
+ # Manual Download
+ sonarrSeriesId = request.args.get('seriesid')
+ sonarrEpisodeId = request.args.get('episodeid')
+ episodeInfo = TableEpisodes.select(TableEpisodes.title,
+ TableEpisodes.path,
+ TableEpisodes.scene_name) \
+ .where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId) \
+ .dicts() \
+ .get()
+
+ title = episodeInfo['title']
+ episodePath = path_mappings.path_replace(episodeInfo['path'])
+ sceneName = episodeInfo['scene_name']
+ if sceneName is None: sceneName = "None"
+
+ language = request.form.get('language')
+ hi = request.form.get('hi').capitalize()
+ forced = request.form.get('forced').capitalize()
+ selected_provider = request.form.get('provider')
+ subtitle = request.form.get('subtitle')
+ providers_auth = get_providers_auth()
+
+ audio_language_list = get_audio_profile_languages(episode_id=sonarrEpisodeId)
+ if len(audio_language_list) > 0:
+ audio_language = audio_language_list[0]['name']
+ else:
+ audio_language = 'None'
+
+ try:
+ result = manual_download_subtitle(episodePath, language, audio_language, hi, forced, subtitle,
+ selected_provider, providers_auth, sceneName, title, 'series',
+ profile_id=get_profile_id(episode_id=sonarrEpisodeId))
+ if result is not None:
+ message = result[0]
+ path = result[1]
+ forced = result[5]
+ if result[8]:
+ language_code = result[2] + ":hi"
+ elif forced:
+ language_code = result[2] + ":forced"
+ else:
+ language_code = result[2]
+ provider = result[3]
+ score = result[4]
+ subs_id = result[6]
+ subs_path = result[7]
+ history_log(2, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score, subs_id,
+ subs_path)
+ if not settings.general.getboolean('dont_notify_manual_actions'):
+ send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
+ store_subtitles(path, episodePath)
+ return result, 201
+ except OSError:
+ pass
+
+ return '', 204
diff --git a/bazarr/api/providers/providers_movies.py b/bazarr/api/providers/providers_movies.py
new file mode 100644
index 000000000..d5c31c1c4
--- /dev/null
+++ b/bazarr/api/providers/providers_movies.py
@@ -0,0 +1,103 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from database import TableMovies, get_audio_profile_languages, get_profile_id
+from helper import path_mappings
+from get_providers import get_providers, get_providers_auth
+from get_subtitle import manual_search, manual_download_subtitle
+from utils import history_log_movie
+from config import settings
+from notifier import send_notifications_movie
+from list_subtitles import store_subtitles_movie
+
+from ..utils import authenticate
+
+
+class ProviderMovies(Resource):
+ @authenticate
+ def get(self):
+ # Manual Search
+ radarrId = request.args.get('radarrid')
+ movieInfo = TableMovies.select(TableMovies.title,
+ TableMovies.path,
+ TableMovies.sceneName,
+ TableMovies.profileId) \
+ .where(TableMovies.radarrId == radarrId) \
+ .dicts() \
+ .get()
+
+ title = movieInfo['title']
+ moviePath = path_mappings.path_replace_movie(movieInfo['path'])
+ sceneName = movieInfo['sceneName']
+ profileId = movieInfo['profileId']
+ if sceneName is None: sceneName = "None"
+
+ providers_list = get_providers()
+ providers_auth = get_providers_auth()
+
+ data = manual_search(moviePath, profileId, providers_list, providers_auth, sceneName, title,
+ 'movie')
+ if not data:
+ data = []
+ return jsonify(data=data)
+
+ @authenticate
+ def post(self):
+ # Manual Download
+ radarrId = request.args.get('radarrid')
+ movieInfo = TableMovies.select(TableMovies.title,
+ TableMovies.path,
+ TableMovies.sceneName,
+ TableMovies.audio_language) \
+ .where(TableMovies.radarrId == radarrId) \
+ .dicts() \
+ .get()
+
+ title = movieInfo['title']
+ moviePath = path_mappings.path_replace_movie(movieInfo['path'])
+ sceneName = movieInfo['sceneName']
+ if sceneName is None: sceneName = "None"
+ audio_language = movieInfo['audio_language']
+
+ language = request.form.get('language')
+ hi = request.form.get('hi').capitalize()
+ forced = request.form.get('forced').capitalize()
+ selected_provider = request.form.get('provider')
+ subtitle = request.form.get('subtitle')
+
+ providers_auth = get_providers_auth()
+
+ audio_language_list = get_audio_profile_languages(movie_id=radarrId)
+ if len(audio_language_list) > 0:
+ audio_language = audio_language_list[0]['name']
+ else:
+ audio_language = 'None'
+
+ try:
+ result = manual_download_subtitle(moviePath, language, audio_language, hi, forced, subtitle,
+ selected_provider, providers_auth, sceneName, title, 'movie',
+ profile_id=get_profile_id(movie_id=radarrId))
+ if result is not None:
+ message = result[0]
+ path = result[1]
+ forced = result[5]
+ if result[8]:
+ language_code = result[2] + ":hi"
+ elif forced:
+ language_code = result[2] + ":forced"
+ else:
+ language_code = result[2]
+ provider = result[3]
+ score = result[4]
+ subs_id = result[6]
+ subs_path = result[7]
+ history_log_movie(2, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
+ if not settings.general.getboolean('dont_notify_manual_actions'):
+ send_notifications_movie(radarrId, message)
+ store_subtitles_movie(path, moviePath)
+ except OSError:
+ pass
+
+ return '', 204
diff --git a/bazarr/api/series/__init__.py b/bazarr/api/series/__init__.py
new file mode 100644
index 000000000..68f437ba4
--- /dev/null
+++ b/bazarr/api/series/__init__.py
@@ -0,0 +1,12 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .series import Series
+
+
+api_bp_series = Blueprint('api_series', __name__)
+api = Api(api_bp_series)
+
+api.add_resource(Series, '/series')
diff --git a/bazarr/api/series/series.py b/bazarr/api/series/series.py
new file mode 100644
index 000000000..057462f11
--- /dev/null
+++ b/bazarr/api/series/series.py
@@ -0,0 +1,114 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+import operator
+from functools import reduce
+
+from database import get_exclusion_clause, TableEpisodes, TableShows
+from list_subtitles import list_missing_subtitles, series_scan_subtitles
+from get_subtitle import series_download_subtitles, wanted_search_missing_subtitles_series
+from ..utils import authenticate, postprocessSeries, None_Keys
+from event_handler import event_stream
+
+
+class Series(Resource):
+ @authenticate
+ def get(self):
+ start = request.args.get('start') or 0
+ length = request.args.get('length') or -1
+ seriesId = request.args.getlist('seriesid[]')
+
+ count = TableShows.select().count()
+
+ if len(seriesId) != 0:
+ result = TableShows.select() \
+ .where(TableShows.sonarrSeriesId.in_(seriesId)) \
+ .order_by(TableShows.sortTitle).dicts()
+ else:
+ result = TableShows.select().order_by(TableShows.sortTitle).limit(length).offset(start).dicts()
+
+ result = list(result)
+
+ for item in result:
+ postprocessSeries(item)
+
+ # Add missing subtitles episode count
+ episodes_missing_conditions = [(TableEpisodes.sonarrSeriesId == item['sonarrSeriesId']),
+ (TableEpisodes.missing_subtitles != '[]')]
+ episodes_missing_conditions += get_exclusion_clause('series')
+
+ episodeMissingCount = TableEpisodes.select(TableShows.tags,
+ TableEpisodes.monitored,
+ TableShows.seriesType) \
+ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \
+ .where(reduce(operator.and_, episodes_missing_conditions)) \
+ .count()
+ item.update({"episodeMissingCount": episodeMissingCount})
+
+ # Add episode count
+ episodeFileCount = TableEpisodes.select(TableShows.tags,
+ TableEpisodes.monitored,
+ TableShows.seriesType) \
+ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \
+ .where(TableEpisodes.sonarrSeriesId == item['sonarrSeriesId']) \
+ .count()
+ item.update({"episodeFileCount": episodeFileCount})
+
+ return jsonify(data=result, total=count)
+
+ @authenticate
+ def post(self):
+ seriesIdList = request.form.getlist('seriesid')
+ profileIdList = request.form.getlist('profileid')
+
+ for idx in range(len(seriesIdList)):
+ seriesId = seriesIdList[idx]
+ profileId = profileIdList[idx]
+
+ if profileId in None_Keys:
+ profileId = None
+ else:
+ try:
+ profileId = int(profileId)
+ except Exception:
+ return '', 400
+
+ TableShows.update({
+ TableShows.profileId: profileId
+ }) \
+ .where(TableShows.sonarrSeriesId == seriesId) \
+ .execute()
+
+ list_missing_subtitles(no=seriesId, send_event=False)
+
+ event_stream(type='series', payload=seriesId)
+
+ episode_id_list = TableEpisodes \
+ .select(TableEpisodes.sonarrEpisodeId) \
+ .where(TableEpisodes.sonarrSeriesId == seriesId) \
+ .dicts()
+
+ for item in episode_id_list:
+ event_stream(type='episode-wanted', payload=item['sonarrEpisodeId'])
+
+ event_stream(type='badges')
+
+ return '', 204
+
+ @authenticate
+ def patch(self):
+ seriesid = request.form.get('seriesid')
+ action = request.form.get('action')
+ if action == "scan-disk":
+ series_scan_subtitles(seriesid)
+ return '', 204
+ elif action == "search-missing":
+ series_download_subtitles(seriesid)
+ return '', 204
+ elif action == "search-wanted":
+ wanted_search_missing_subtitles_series()
+ return '', 204
+
+ return '', 400
diff --git a/bazarr/api/subtitles/__init__.py b/bazarr/api/subtitles/__init__.py
new file mode 100644
index 000000000..7cb7d9a11
--- /dev/null
+++ b/bazarr/api/subtitles/__init__.py
@@ -0,0 +1,14 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .subtitles import Subtitles
+from .subtitles_info import SubtitleNameInfo
+
+
+api_bp_subtitles = Blueprint('api_subtitles', __name__)
+api = Api(api_bp_subtitles)
+
+api.add_resource(Subtitles, '/subtitles')
+api.add_resource(SubtitleNameInfo, '/subtitles/info')
diff --git a/bazarr/api/subtitles/subtitles.py b/bazarr/api/subtitles/subtitles.py
new file mode 100644
index 000000000..7799a9679
--- /dev/null
+++ b/bazarr/api/subtitles/subtitles.py
@@ -0,0 +1,72 @@
+# coding=utf-8
+
+import os
+import sys
+
+from flask import request
+from flask_restful import Resource
+
+from database import TableEpisodes, TableMovies
+from helper import path_mappings
+from ..utils import authenticate
+from subsyncer import subsync
+from utils import translate_subtitles_file, subtitles_apply_mods
+from get_subtitle import store_subtitles, store_subtitles_movie
+from config import settings
+
+
+class Subtitles(Resource):
+ @authenticate
+ def patch(self):
+ action = request.args.get('action')
+
+ language = request.form.get('language')
+ subtitles_path = request.form.get('path')
+ media_type = request.form.get('type')
+ id = request.form.get('id')
+
+ if media_type == 'episode':
+ subtitles_path = path_mappings.path_replace(subtitles_path)
+ metadata = TableEpisodes.select(TableEpisodes.path, TableEpisodes.sonarrSeriesId)\
+ .where(TableEpisodes.sonarrEpisodeId == id)\
+ .dicts()\
+ .get()
+ video_path = path_mappings.path_replace(metadata['path'])
+ else:
+ subtitles_path = path_mappings.path_replace_movie(subtitles_path)
+ metadata = TableMovies.select(TableMovies.path).where(TableMovies.radarrId == id).dicts().get()
+ video_path = path_mappings.path_replace_movie(metadata['path'])
+
+ if action == 'sync':
+ if media_type == 'episode':
+ subsync.sync(video_path=video_path, srt_path=subtitles_path,
+ srt_lang=language, media_type='series', sonarr_series_id=metadata['sonarrSeriesId'],
+ sonarr_episode_id=int(id))
+ else:
+ subsync.sync(video_path=video_path, srt_path=subtitles_path,
+ srt_lang=language, media_type='movies', radarr_id=id)
+ elif action == 'translate':
+ dest_language = language
+ forced = True if request.form.get('forced') == 'true' else False
+ hi = True if request.form.get('hi') == 'true' else False
+ result = translate_subtitles_file(video_path=video_path, source_srt_file=subtitles_path,
+ to_lang=dest_language,
+ forced=forced, hi=hi)
+ if result:
+ if media_type == 'episode':
+ store_subtitles(path_mappings.path_replace_reverse(video_path), video_path)
+ else:
+ store_subtitles_movie(path_mappings.path_replace_reverse_movie(video_path), video_path)
+ return '', 200
+ else:
+ return '', 404
+ else:
+ subtitles_apply_mods(language, subtitles_path, [action])
+
+ # apply chmod if required
+ chmod = int(settings.general.chmod, 8) if not sys.platform.startswith(
+ 'win') and settings.general.getboolean('chmod_enabled') else None
+ if chmod:
+ os.chmod(subtitles_path, chmod)
+
+ return '', 204
diff --git a/bazarr/api/subtitles/subtitles_info.py b/bazarr/api/subtitles/subtitles_info.py
new file mode 100644
index 000000000..9de38ac55
--- /dev/null
+++ b/bazarr/api/subtitles/subtitles_info.py
@@ -0,0 +1,41 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+from subliminal_patch.core import guessit
+from ..utils import authenticate
+
+
+class SubtitleNameInfo(Resource):
+ @authenticate
+ def get(self):
+ names = request.args.getlist('filenames[]')
+ results = []
+ for name in names:
+ opts = dict()
+ opts['type'] = 'episode'
+ guessit_result = guessit(name, options=opts)
+ result = {}
+ result['filename'] = name
+ if 'subtitle_language' in guessit_result:
+ result['subtitle_language'] = str(guessit_result['subtitle_language'])
+
+ result['episode'] = 0
+ if 'episode' in guessit_result:
+ if isinstance(guessit_result['episode'], list):
+ # for multiple episodes file, choose the first episode number
+ if len(guessit_result['episode']):
+ # make sure that guessit returned a list of more than 0 items
+ result['episode'] = int(guessit_result['episode'][0])
+ elif isinstance(guessit_result['episode'], (str, int)):
+ # if single episode (should be int but just in case we cast it to int)
+ result['episode'] = int(guessit_result['episode'])
+
+ if 'season' in guessit_result:
+ result['season'] = int(guessit_result['season'])
+ else:
+ result['season'] = 0
+
+ results.append(result)
+
+ return jsonify(data=results)
diff --git a/bazarr/api/system/__init__.py b/bazarr/api/system/__init__.py
new file mode 100644
index 000000000..cbe54a13b
--- /dev/null
+++ b/bazarr/api/system/__init__.py
@@ -0,0 +1,33 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .system import System
+from .searches import Searches
+from .account import SystemAccount
+from .tasks import SystemTasks
+from .logs import SystemLogs
+from .status import SystemStatus
+from .health import SystemHealth
+from .releases import SystemReleases
+from .settings import SystemSettings
+from .languages import Languages
+from .languages_profiles import LanguagesProfiles
+from .notifications import Notifications
+
+api_bp_system = Blueprint('api_system', __name__)
+api = Api(api_bp_system)
+
+api.add_resource(System, '/system')
+api.add_resource(Searches, '/system/searches')
+api.add_resource(SystemAccount, '/system/account')
+api.add_resource(SystemTasks, '/system/tasks')
+api.add_resource(SystemLogs, '/system/logs')
+api.add_resource(SystemStatus, '/system/status')
+api.add_resource(SystemHealth, '/system/health')
+api.add_resource(SystemReleases, '/system/releases')
+api.add_resource(SystemSettings, '/system/settings')
+api.add_resource(Languages, '/system/languages')
+api.add_resource(LanguagesProfiles, '/system/languages/profiles')
+api.add_resource(Notifications, '/system/notifications')
diff --git a/bazarr/api/system/account.py b/bazarr/api/system/account.py
new file mode 100644
index 000000000..a46e2b331
--- /dev/null
+++ b/bazarr/api/system/account.py
@@ -0,0 +1,29 @@
+# coding=utf-8
+
+import gc
+
+from flask import request, session
+from flask_restful import Resource
+
+from config import settings
+from utils import check_credentials
+
+
+class SystemAccount(Resource):
+ def post(self):
+ if settings.auth.type != 'form':
+ return '', 405
+
+ action = request.args.get('action')
+ if action == 'login':
+ username = request.form.get('username')
+ password = request.form.get('password')
+ if check_credentials(username, password):
+ session['logged_in'] = True
+ return '', 204
+ elif action == 'logout':
+ session.clear()
+ gc.collect()
+ return '', 204
+
+ return '', 401
diff --git a/bazarr/api/system/health.py b/bazarr/api/system/health.py
new file mode 100644
index 000000000..3db5374a1
--- /dev/null
+++ b/bazarr/api/system/health.py
@@ -0,0 +1,13 @@
+# coding=utf-8
+
+from flask import jsonify
+from flask_restful import Resource
+
+from ..utils import authenticate
+from utils import get_health_issues
+
+
+class SystemHealth(Resource):
+ @authenticate
+ def get(self):
+ return jsonify(data=get_health_issues())
diff --git a/bazarr/api/system/languages.py b/bazarr/api/system/languages.py
new file mode 100644
index 000000000..0f69a8eea
--- /dev/null
+++ b/bazarr/api/system/languages.py
@@ -0,0 +1,54 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from operator import itemgetter
+
+from ..utils import authenticate, False_Keys
+from database import TableHistory, TableHistoryMovie, TableSettingsLanguages
+from get_languages import alpha2_from_alpha3, language_from_alpha2
+
+
+class Languages(Resource):
+ @authenticate
+ def get(self):
+ history = request.args.get('history')
+ if history and history not in False_Keys:
+ languages = list(TableHistory.select(TableHistory.language)
+ .where(TableHistory.language != None)
+ .dicts())
+ languages += list(TableHistoryMovie.select(TableHistoryMovie.language)
+ .where(TableHistoryMovie.language != None)
+ .dicts())
+ languages_list = list(set([l['language'].split(':')[0] for l in languages]))
+ languages_dicts = []
+ for language in languages_list:
+ code2 = None
+ if len(language) == 2:
+ code2 = language
+ elif len(language) == 3:
+ code2 = alpha2_from_alpha3(language)
+ else:
+ continue
+
+ if not any(x['code2'] == code2 for x in languages_dicts):
+ try:
+ languages_dicts.append({
+ 'code2': code2,
+ 'name': language_from_alpha2(code2),
+ # Compatibility: Use false temporarily
+ 'enabled': False
+ })
+ except:
+ continue
+ return jsonify(sorted(languages_dicts, key=itemgetter('name')))
+
+ result = TableSettingsLanguages.select(TableSettingsLanguages.name,
+ TableSettingsLanguages.code2,
+ TableSettingsLanguages.enabled)\
+ .order_by(TableSettingsLanguages.name).dicts()
+ result = list(result)
+ for item in result:
+ item['enabled'] = item['enabled'] == 1
+ return jsonify(result)
diff --git a/bazarr/api/system/languages_profiles.py b/bazarr/api/system/languages_profiles.py
new file mode 100644
index 000000000..15e8f3cb7
--- /dev/null
+++ b/bazarr/api/system/languages_profiles.py
@@ -0,0 +1,13 @@
+# coding=utf-8
+
+from flask import jsonify
+from flask_restful import Resource
+
+from ..utils import authenticate
+from database import get_profiles_list
+
+
+class LanguagesProfiles(Resource):
+ @authenticate
+ def get(self):
+ return jsonify(get_profiles_list())
diff --git a/bazarr/api/system/logs.py b/bazarr/api/system/logs.py
new file mode 100644
index 000000000..83b8546c2
--- /dev/null
+++ b/bazarr/api/system/logs.py
@@ -0,0 +1,41 @@
+# coding=utf-8
+
+import io
+import os
+
+from flask import jsonify
+from flask_restful import Resource
+
+from ..utils import authenticate
+from logger import empty_log
+from get_args import args
+
+
+class SystemLogs(Resource):
+ @authenticate
+ def get(self):
+ logs = []
+ with io.open(os.path.join(args.config_dir, 'log', 'bazarr.log'), encoding='UTF-8') as file:
+ raw_lines = file.read()
+ lines = raw_lines.split('|\n')
+ for line in lines:
+ if line == '':
+ continue
+ raw_message = line.split('|')
+ raw_message_len = len(raw_message)
+ if raw_message_len > 3:
+ log = dict()
+ log["timestamp"] = raw_message[0]
+ log["type"] = raw_message[1].rstrip()
+ log["message"] = raw_message[3]
+ if raw_message_len > 4 and raw_message[4] != '\n':
+ log['exception'] = raw_message[4].strip('\'').replace(' ', '\u2003\u2003')
+ logs.append(log)
+
+ logs.reverse()
+ return jsonify(data=logs)
+
+ @authenticate
+ def delete(self):
+ empty_log()
+ return '', 204
diff --git a/bazarr/api/system/notifications.py b/bazarr/api/system/notifications.py
new file mode 100644
index 000000000..4cb8e24a1
--- /dev/null
+++ b/bazarr/api/system/notifications.py
@@ -0,0 +1,27 @@
+# coding=utf-8
+
+import apprise
+
+from flask import request
+from flask_restful import Resource
+
+from ..utils import authenticate
+
+
+class Notifications(Resource):
+ @authenticate
+ def patch(self):
+ url = request.form.get("url")
+
+ asset = apprise.AppriseAsset(async_mode=False)
+
+ apobj = apprise.Apprise(asset=asset)
+
+ apobj.add(url)
+
+ apobj.notify(
+ title='Bazarr test notification',
+ body='Test notification'
+ )
+
+ return '', 204
diff --git a/bazarr/api/system/releases.py b/bazarr/api/system/releases.py
new file mode 100644
index 000000000..150cb083f
--- /dev/null
+++ b/bazarr/api/system/releases.py
@@ -0,0 +1,47 @@
+# coding=utf-8
+
+import io
+import json
+import os
+import logging
+
+from flask import jsonify
+from flask_restful import Resource
+
+from ..utils import authenticate
+from config import settings
+from get_args import args
+
+
+class SystemReleases(Resource):
+ @authenticate
+ def get(self):
+ filtered_releases = []
+ try:
+ with io.open(os.path.join(args.config_dir, 'config', 'releases.txt'), 'r', encoding='UTF-8') as f:
+ releases = json.loads(f.read())
+
+ for release in releases:
+ if settings.general.branch == 'master' and not release['prerelease']:
+ filtered_releases.append(release)
+ elif settings.general.branch != 'master' and any(not x['prerelease'] for x in filtered_releases):
+ continue
+ elif settings.general.branch != 'master':
+ filtered_releases.append(release)
+ if settings.general.branch == 'master':
+ filtered_releases = filtered_releases[:5]
+
+ current_version = os.environ["BAZARR_VERSION"]
+
+ for i, release in enumerate(filtered_releases):
+ body = release['body'].replace('- ', '').split('\n')[1:]
+ filtered_releases[i] = {"body": body,
+ "name": release['name'],
+ "date": release['date'][:10],
+ "prerelease": release['prerelease'],
+ "current": release['name'].lstrip('v') == current_version}
+
+ except Exception:
+ logging.exception(
+ 'BAZARR cannot parse releases caching file: ' + os.path.join(args.config_dir, 'config', 'releases.txt'))
+ return jsonify(data=filtered_releases)
diff --git a/bazarr/api/system/searches.py b/bazarr/api/system/searches.py
new file mode 100644
index 000000000..c85fa82bf
--- /dev/null
+++ b/bazarr/api/system/searches.py
@@ -0,0 +1,41 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from ..utils import authenticate
+from config import settings
+from database import TableShows, TableMovies
+
+
+class Searches(Resource):
+ @authenticate
+ def get(self):
+ query = request.args.get('query')
+ search_list = []
+
+ if query:
+ if settings.general.getboolean('use_sonarr'):
+ # Get matching series
+ series = TableShows.select(TableShows.title,
+ TableShows.sonarrSeriesId,
+ TableShows.year)\
+ .where(TableShows.title.contains(query))\
+ .order_by(TableShows.title)\
+ .dicts()
+ series = list(series)
+ search_list += series
+
+ if settings.general.getboolean('use_radarr'):
+ # Get matching movies
+ movies = TableMovies.select(TableMovies.title,
+ TableMovies.radarrId,
+ TableMovies.year) \
+ .where(TableMovies.title.contains(query)) \
+ .order_by(TableMovies.title) \
+ .dicts()
+ movies = list(movies)
+ search_list += movies
+
+
+ return jsonify(search_list)
diff --git a/bazarr/api/system/settings.py b/bazarr/api/system/settings.py
new file mode 100644
index 000000000..8cdbc90f3
--- /dev/null
+++ b/bazarr/api/system/settings.py
@@ -0,0 +1,106 @@
+# coding=utf-8
+
+import json
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from ..utils import authenticate
+from database import TableLanguagesProfiles, TableSettingsLanguages, TableShows, TableMovies, TableSettingsNotifier, \
+ update_profile_id_list
+from event_handler import event_stream
+from config import settings, save_settings, get_settings
+from scheduler import scheduler
+from list_subtitles import list_missing_subtitles, list_missing_subtitles_movies
+
+
+class SystemSettings(Resource):
+ @authenticate
+ def get(self):
+ data = get_settings()
+
+ notifications = TableSettingsNotifier.select().order_by(TableSettingsNotifier.name).dicts()
+ notifications = list(notifications)
+ for i, item in enumerate(notifications):
+ item["enabled"] = item["enabled"] == 1
+ notifications[i] = item
+
+ data['notifications'] = dict()
+ data['notifications']['providers'] = notifications
+
+ return jsonify(data)
+
+ @authenticate
+ def post(self):
+ enabled_languages = request.form.getlist('languages-enabled')
+ if len(enabled_languages) != 0:
+ TableSettingsLanguages.update({
+ TableSettingsLanguages.enabled: 0
+ }).execute()
+ for code in enabled_languages:
+ TableSettingsLanguages.update({
+ TableSettingsLanguages.enabled: 1
+ })\
+ .where(TableSettingsLanguages.code2 == code)\
+ .execute()
+ event_stream("languages")
+
+ languages_profiles = request.form.get('languages-profiles')
+ if languages_profiles:
+ existing_ids = TableLanguagesProfiles.select(TableLanguagesProfiles.profileId).dicts()
+ existing_ids = list(existing_ids)
+ existing = [x['profileId'] for x in existing_ids]
+ for item in json.loads(languages_profiles):
+ if item['profileId'] in existing:
+ # Update existing profiles
+ TableLanguagesProfiles.update({
+ TableLanguagesProfiles.name: item['name'],
+ TableLanguagesProfiles.cutoff: item['cutoff'] if item['cutoff'] != 'null' else None,
+ TableLanguagesProfiles.items: json.dumps(item['items']),
+ TableLanguagesProfiles.mustContain: item['mustContain'],
+ TableLanguagesProfiles.mustNotContain: item['mustNotContain'],
+ })\
+ .where(TableLanguagesProfiles.profileId == item['profileId'])\
+ .execute()
+ existing.remove(item['profileId'])
+ else:
+ # Add new profiles
+ TableLanguagesProfiles.insert({
+ TableLanguagesProfiles.profileId: item['profileId'],
+ TableLanguagesProfiles.name: item['name'],
+ TableLanguagesProfiles.cutoff: item['cutoff'] if item['cutoff'] != 'null' else None,
+ TableLanguagesProfiles.items: json.dumps(item['items']),
+ TableLanguagesProfiles.mustContain: item['mustContain'],
+ TableLanguagesProfiles.mustNotContain: item['mustNotContain'],
+ }).execute()
+ for profileId in existing:
+ # Unassign this profileId from series and movies
+ TableShows.update({
+ TableShows.profileId: None
+ }).where(TableShows.profileId == profileId).execute()
+ TableMovies.update({
+ TableMovies.profileId: None
+ }).where(TableMovies.profileId == profileId).execute()
+ # Remove deleted profiles
+ TableLanguagesProfiles.delete().where(TableLanguagesProfiles.profileId == profileId).execute()
+
+ update_profile_id_list()
+ event_stream("languages")
+
+ if settings.general.getboolean('use_sonarr'):
+ scheduler.add_job(list_missing_subtitles, kwargs={'send_event': False})
+ if settings.general.getboolean('use_radarr'):
+ scheduler.add_job(list_missing_subtitles_movies, kwargs={'send_event': False})
+
+ # Update Notification
+ notifications = request.form.getlist('notifications-providers')
+ for item in notifications:
+ item = json.loads(item)
+ TableSettingsNotifier.update({
+ TableSettingsNotifier.enabled: item['enabled'],
+ TableSettingsNotifier.url: item['url']
+ }).where(TableSettingsNotifier.name == item['name']).execute()
+
+ save_settings(zip(request.form.keys(), request.form.listvalues()))
+ event_stream("settings")
+ return '', 204
diff --git a/bazarr/api/system/status.py b/bazarr/api/system/status.py
new file mode 100644
index 000000000..4a8b69a16
--- /dev/null
+++ b/bazarr/api/system/status.py
@@ -0,0 +1,27 @@
+# coding=utf-8
+
+import os
+import platform
+
+from flask import jsonify
+from flask_restful import Resource
+
+from ..utils import authenticate
+from utils import get_sonarr_info, get_radarr_info
+from get_args import args
+from init import startTime
+
+
+class SystemStatus(Resource):
+ @authenticate
+ def get(self):
+ system_status = {}
+ system_status.update({'bazarr_version': os.environ["BAZARR_VERSION"]})
+ system_status.update({'sonarr_version': get_sonarr_info.version()})
+ system_status.update({'radarr_version': get_radarr_info.version()})
+ system_status.update({'operating_system': platform.platform()})
+ system_status.update({'python_version': platform.python_version()})
+ system_status.update({'bazarr_directory': os.path.dirname(os.path.dirname(__file__))})
+ system_status.update({'bazarr_config_directory': args.config_dir})
+ system_status.update({'start_time': startTime})
+ return jsonify(data=system_status)
diff --git a/bazarr/api/system/system.py b/bazarr/api/system/system.py
new file mode 100644
index 000000000..98b614523
--- /dev/null
+++ b/bazarr/api/system/system.py
@@ -0,0 +1,18 @@
+# coding=utf-8
+
+from flask import request
+from flask_restful import Resource
+
+from ..utils import authenticate
+
+
+class System(Resource):
+ @authenticate
+ def post(self):
+ from server import webserver
+ action = request.args.get('action')
+ if action == "shutdown":
+ webserver.shutdown()
+ elif action == "restart":
+ webserver.restart()
+ return '', 204
diff --git a/bazarr/api/system/tasks.py b/bazarr/api/system/tasks.py
new file mode 100644
index 000000000..0bdfed429
--- /dev/null
+++ b/bazarr/api/system/tasks.py
@@ -0,0 +1,31 @@
+# coding=utf-8
+
+from flask import request, jsonify
+from flask_restful import Resource
+
+from ..utils import authenticate
+from scheduler import scheduler
+
+
+class SystemTasks(Resource):
+ @authenticate
+ def get(self):
+ taskid = request.args.get('taskid')
+
+ task_list = scheduler.get_task_list()
+
+ if taskid:
+ for item in task_list:
+ if item['job_id'] == taskid:
+ task_list = [item]
+ continue
+
+ return jsonify(data=task_list)
+
+ @authenticate
+ def post(self):
+ taskid = request.form.get('taskid')
+
+ scheduler.execute_job_now(taskid)
+
+ return '', 204
diff --git a/bazarr/api/utils.py b/bazarr/api/utils.py
new file mode 100644
index 000000000..61e19c947
--- /dev/null
+++ b/bazarr/api/utils.py
@@ -0,0 +1,239 @@
+# coding=utf-8
+
+import ast
+
+from functools import wraps
+from flask import request, abort
+from operator import itemgetter
+
+from config import settings, base_url
+from get_languages import language_from_alpha2, alpha3_from_alpha2
+from database import get_audio_profile_languages, get_desired_languages
+from helper import path_mappings
+
+None_Keys = ['null', 'undefined', '', None]
+
+False_Keys = ['False', 'false', '0']
+
+
+def authenticate(actual_method):
+ @wraps(actual_method)
+ def wrapper(*args, **kwargs):
+ apikey_settings = settings.auth.apikey
+ apikey_get = request.args.get('apikey')
+ apikey_post = request.form.get('apikey')
+ apikey_header = None
+ if 'X-API-KEY' in request.headers:
+ apikey_header = request.headers['X-API-KEY']
+
+ if apikey_settings in [apikey_get, apikey_post, apikey_header]:
+ return actual_method(*args, **kwargs)
+
+ return abort(401)
+
+ return wrapper
+
+
+def postprocess(item):
+ # Remove ffprobe_cache
+ if 'ffprobe_cache' in item:
+ del (item['ffprobe_cache'])
+
+ # Parse tags
+ if 'tags' in item:
+ if item['tags'] is None:
+ item['tags'] = []
+ else:
+ item['tags'] = ast.literal_eval(item['tags'])
+
+ if 'monitored' in item:
+ if item['monitored'] is None:
+ item['monitored'] = False
+ else:
+ item['monitored'] = item['monitored'] == 'True'
+
+ if 'hearing_impaired' in item and item['hearing_impaired'] is not None:
+ if item['hearing_impaired'] is None:
+ item['hearing_impaired'] = False
+ else:
+ item['hearing_impaired'] = item['hearing_impaired'] == 'True'
+
+ if 'language' in item:
+ if item['language'] == 'None':
+ item['language'] = None
+ elif item['language'] is not None:
+ splitted_language = item['language'].split(':')
+ item['language'] = {"name": language_from_alpha2(splitted_language[0]),
+ "code2": splitted_language[0],
+ "code3": alpha3_from_alpha2(splitted_language[0]),
+ "forced": True if item['language'].endswith(':forced') else False,
+ "hi": True if item['language'].endswith(':hi') else False}
+
+
+def postprocessSeries(item):
+ postprocess(item)
+ # Parse audio language
+ if 'audio_language' in item and item['audio_language'] is not None:
+ item['audio_language'] = get_audio_profile_languages(series_id=item['sonarrSeriesId'])
+
+ if 'alternateTitles' in item:
+ if item['alternateTitles'] is None:
+ item['alternativeTitles'] = []
+ else:
+ item['alternativeTitles'] = ast.literal_eval(item['alternateTitles'])
+ del item["alternateTitles"]
+
+ # Parse seriesType
+ if 'seriesType' in item and item['seriesType'] is not None:
+ item['seriesType'] = item['seriesType'].capitalize()
+
+ if 'path' in item:
+ item['path'] = path_mappings.path_replace(item['path'])
+
+ # map poster and fanart to server proxy
+ if 'poster' in item:
+ poster = item['poster']
+ item['poster'] = f"{base_url}/images/series{poster}" if poster else None
+
+ if 'fanart' in item:
+ fanart = item['fanart']
+ item['fanart'] = f"{base_url}/images/series{fanart}" if fanart else None
+
+
+def postprocessEpisode(item):
+ postprocess(item)
+ if 'audio_language' in item and item['audio_language'] is not None:
+ item['audio_language'] = get_audio_profile_languages(episode_id=item['sonarrEpisodeId'])
+
+ if 'subtitles' in item:
+ if item['subtitles'] is None:
+ raw_subtitles = []
+ else:
+ raw_subtitles = ast.literal_eval(item['subtitles'])
+ subtitles = []
+
+ for subs in raw_subtitles:
+ subtitle = subs[0].split(':')
+ sub = {"name": language_from_alpha2(subtitle[0]),
+ "code2": subtitle[0],
+ "code3": alpha3_from_alpha2(subtitle[0]),
+ "path": path_mappings.path_replace(subs[1]),
+ "forced": False,
+ "hi": False}
+ if len(subtitle) > 1:
+ sub["forced"] = True if subtitle[1] == 'forced' else False
+ sub["hi"] = True if subtitle[1] == 'hi' else False
+
+ subtitles.append(sub)
+
+ item.update({"subtitles": subtitles})
+
+ # Parse missing subtitles
+ if 'missing_subtitles' in item:
+ if item['missing_subtitles'] is None:
+ item['missing_subtitles'] = []
+ else:
+ item['missing_subtitles'] = ast.literal_eval(item['missing_subtitles'])
+ for i, subs in enumerate(item['missing_subtitles']):
+ subtitle = subs.split(':')
+ item['missing_subtitles'][i] = {"name": language_from_alpha2(subtitle[0]),
+ "code2": subtitle[0],
+ "code3": alpha3_from_alpha2(subtitle[0]),
+ "forced": False,
+ "hi": False}
+ if len(subtitle) > 1:
+ item['missing_subtitles'][i].update({
+ "forced": True if subtitle[1] == 'forced' else False,
+ "hi": True if subtitle[1] == 'hi' else False
+ })
+
+ if 'scene_name' in item:
+ item["sceneName"] = item["scene_name"]
+ del item["scene_name"]
+
+ if 'path' in item and item['path']:
+ # Provide mapped path
+ item['path'] = path_mappings.path_replace(item['path'])
+
+
+# TODO: Move
+def postprocessMovie(item):
+ postprocess(item)
+ # Parse audio language
+ if 'audio_language' in item and item['audio_language'] is not None:
+ item['audio_language'] = get_audio_profile_languages(movie_id=item['radarrId'])
+
+ # Parse alternate titles
+ if 'alternativeTitles' in item:
+ if item['alternativeTitles'] is None:
+ item['alternativeTitles'] = []
+ else:
+ item['alternativeTitles'] = ast.literal_eval(item['alternativeTitles'])
+
+ # Parse failed attempts
+ if 'failedAttempts' in item:
+ if item['failedAttempts']:
+ item['failedAttempts'] = ast.literal_eval(item['failedAttempts'])
+
+ # Parse subtitles
+ if 'subtitles' in item:
+ if item['subtitles'] is None:
+ item['subtitles'] = []
+ else:
+ item['subtitles'] = ast.literal_eval(item['subtitles'])
+ for i, subs in enumerate(item['subtitles']):
+ language = subs[0].split(':')
+ item['subtitles'][i] = {"path": path_mappings.path_replace_movie(subs[1]),
+ "name": language_from_alpha2(language[0]),
+ "code2": language[0],
+ "code3": alpha3_from_alpha2(language[0]),
+ "forced": False,
+ "hi": False}
+ if len(language) > 1:
+ item['subtitles'][i].update({
+ "forced": True if language[1] == 'forced' else False,
+ "hi": True if language[1] == 'hi' else False
+ })
+
+ if settings.general.getboolean('embedded_subs_show_desired'):
+ desired_lang_list = get_desired_languages(item['profileId'])
+ item['subtitles'] = [x for x in item['subtitles'] if x['code2'] in desired_lang_list or x['path']]
+
+ item['subtitles'] = sorted(item['subtitles'], key=itemgetter('name', 'forced'))
+
+ # Parse missing subtitles
+ if 'missing_subtitles' in item:
+ if item['missing_subtitles'] is None:
+ item['missing_subtitles'] = []
+ else:
+ item['missing_subtitles'] = ast.literal_eval(item['missing_subtitles'])
+ for i, subs in enumerate(item['missing_subtitles']):
+ language = subs.split(':')
+ item['missing_subtitles'][i] = {"name": language_from_alpha2(language[0]),
+ "code2": language[0],
+ "code3": alpha3_from_alpha2(language[0]),
+ "forced": False,
+ "hi": False}
+ if len(language) > 1:
+ item['missing_subtitles'][i].update({
+ "forced": True if language[1] == 'forced' else False,
+ "hi": True if language[1] == 'hi' else False
+ })
+
+ # Provide mapped path
+ if 'path' in item:
+ if item['path']:
+ item['path'] = path_mappings.path_replace_movie(item['path'])
+
+ if 'subtitles_path' in item:
+ # Provide mapped subtitles path
+ item['subtitles_path'] = path_mappings.path_replace_movie(item['subtitles_path'])
+
+ # map poster and fanart to server proxy
+ if 'poster' in item:
+ poster = item['poster']
+ item['poster'] = f"{base_url}/images/movies{poster}" if poster else None
+
+ if 'fanart' in item:
+ fanart = item['fanart']
+ item['fanart'] = f"{base_url}/images/movies{fanart}" if fanart else None
diff --git a/bazarr/api/webhooks/__init__.py b/bazarr/api/webhooks/__init__.py
new file mode 100644
index 000000000..76b8d62ff
--- /dev/null
+++ b/bazarr/api/webhooks/__init__.py
@@ -0,0 +1,12 @@
+# coding=utf-8
+
+from flask import Blueprint
+from flask_restful import Api
+
+from .plex import WebHooksPlex
+
+
+api_bp_webhooks = Blueprint('api_webhooks', __name__)
+api = Api(api_bp_webhooks)
+
+api.add_resource(WebHooksPlex, '/webhooks/plex')
diff --git a/bazarr/api/webhooks/plex.py b/bazarr/api/webhooks/plex.py
new file mode 100644
index 000000000..6cc6e9da8
--- /dev/null
+++ b/bazarr/api/webhooks/plex.py
@@ -0,0 +1,76 @@
+# coding=utf-8
+
+import json
+import requests
+import os
+import re
+
+from flask import request
+from flask_restful import Resource
+from bs4 import BeautifulSoup as bso
+
+from database import TableEpisodes, TableShows, TableMovies
+from get_subtitle import episode_download_subtitles, movies_download_subtitles
+from ..utils import authenticate
+
+
+class WebHooksPlex(Resource):
+ @authenticate
+ def post(self):
+ json_webhook = request.form.get('payload')
+ parsed_json_webhook = json.loads(json_webhook)
+
+ event = parsed_json_webhook['event']
+ if event not in ['media.play']:
+ return '', 204
+
+ media_type = parsed_json_webhook['Metadata']['type']
+
+ if media_type == 'episode':
+ season = parsed_json_webhook['Metadata']['parentIndex']
+ episode = parsed_json_webhook['Metadata']['index']
+ else:
+ season = episode = None
+
+ ids = []
+ for item in parsed_json_webhook['Metadata']['Guid']:
+ splitted_id = item['id'].split('://')
+ if len(splitted_id) == 2:
+ ids.append({splitted_id[0]: splitted_id[1]})
+ if not ids:
+ return '', 404
+
+ if media_type == 'episode':
+ try:
+ episode_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0]
+ r = requests.get('https://imdb.com/title/{}'.format(episode_imdb_id),
+ headers={"User-Agent": os.environ["SZ_USER_AGENT"]})
+ soup = bso(r.content, "html.parser")
+ series_imdb_id = soup.find('a', {'class': re.compile(r'SeriesParentLink__ParentTextLink')})['href'].split('/')[2]
+ except:
+ return '', 404
+ else:
+ sonarrEpisodeId = TableEpisodes.select(TableEpisodes.sonarrEpisodeId) \
+ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \
+ .where(TableShows.imdbId == series_imdb_id,
+ TableEpisodes.season == season,
+ TableEpisodes.episode == episode) \
+ .dicts() \
+ .get()
+
+ if sonarrEpisodeId:
+ episode_download_subtitles(no=sonarrEpisodeId['sonarrEpisodeId'], send_progress=True)
+ else:
+ try:
+ movie_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0]
+ except:
+ return '', 404
+ else:
+ radarrId = TableMovies.select(TableMovies.radarrId)\
+ .where(TableMovies.imdbId == movie_imdb_id)\
+ .dicts()\
+ .get()
+ if radarrId:
+ movies_download_subtitles(no=radarrId['radarrId'])
+
+ return '', 200
diff --git a/bazarr/app.py b/bazarr/app.py
index a67810c57..48560e443 100644
--- a/bazarr/app.py
+++ b/bazarr/app.py
@@ -28,7 +28,8 @@ def create_app():
else:
app.config["DEBUG"] = False
- socketio.init_app(app, path=base_url.rstrip('/')+'/api/socket.io', cors_allowed_origins='*', async_mode='threading')
+ socketio.init_app(app, path=base_url.rstrip('/')+'/api/socket.io', cors_allowed_origins='*',
+ async_mode='threading', allow_upgrades=False, transports='polling')
return app
diff --git a/bazarr/check_update.py b/bazarr/check_update.py
index 96c88e92d..3b73962a6 100644
--- a/bazarr/check_update.py
+++ b/bazarr/check_update.py
@@ -193,7 +193,7 @@ def update_cleaner(zipfile, bazarr_dir, config_dir):
'^venv' + separator,
'^WinPython' + separator,
separator + '__pycache__' + separator + '$']
- if os.path.abspath(bazarr_dir) in os.path.abspath(config_dir):
+ if os.path.abspath(bazarr_dir).lower() in os.path.abspath(config_dir).lower():
dir_to_ignore.append('^' + os.path.relpath(config_dir, bazarr_dir) + os.path.sep)
dir_to_ignore_regex = re.compile('(?:% s)' % '|'.join(dir_to_ignore))
logging.debug('BAZARR upgrade leftover cleaner will ignore directories matching this regex: '
diff --git a/bazarr/config.py b/bazarr/config.py
index af581c352..62eba3088 100644
--- a/bazarr/config.py
+++ b/bazarr/config.py
@@ -57,6 +57,8 @@ defaults = {
'ignore_vobsub_subs': 'False',
'ignore_ass_subs': 'False',
'adaptive_searching': 'False',
+ 'adaptive_searching_delay': '3w',
+ 'adaptive_searching_delta': '1w',
'enabled_providers': '[]',
'multithreading': 'True',
'chmod_enabled': 'False',
@@ -92,7 +94,8 @@ defaults = {
'episodes_sync': '60',
'excluded_tags': '[]',
'excluded_series_types': '[]',
- 'use_ffprobe_cache': 'True'
+ 'use_ffprobe_cache': 'True',
+ 'exclude_season_zero': 'False'
},
'radarr': {
'ip': '127.0.0.1',
@@ -132,7 +135,8 @@ defaults = {
},
'addic7ed': {
'username': '',
- 'password': ''
+ 'password': '',
+ 'vip': 'False'
},
'podnapisi': {
'verify_ssl': 'True'
@@ -190,6 +194,10 @@ defaults = {
'approved_only': 'False',
'multithreading': 'True'
},
+ 'embeddedsubtitles': {
+ 'include_ass': 'True',
+ 'include_srt': 'True',
+ },
'subsync': {
'use_subsync': 'False',
'use_subsync_threshold': 'False',
@@ -388,12 +396,12 @@ def save_settings(settings_items):
configure_proxy = True
if key in ['settings-sonarr-excluded_tags', 'settings-sonarr-only_monitored',
- 'settings-sonarr-excluded_series_types', 'settings.radarr.excluded_tags',
- 'settings-radarr-only_monitored']:
+ 'settings-sonarr-excluded_series_types', 'settings-sonarr-exclude_season_zero',
+ 'settings.radarr.excluded_tags', 'settings-radarr-only_monitored']:
exclusion_updated = True
if key in ['settings-sonarr-excluded_tags', 'settings-sonarr-only_monitored',
- 'settings-sonarr-excluded_series_types']:
+ 'settings-sonarr-excluded_series_types', 'settings-sonarr-exclude_season_zero']:
sonarr_exclusion_updated = True
if key in ['settings.radarr.excluded_tags', 'settings-radarr-only_monitored']:
@@ -463,8 +471,10 @@ def save_settings(settings_items):
configure_captcha_func()
if update_schedule:
- from api import scheduler
+ from scheduler import scheduler
+ from event_handler import event_stream
scheduler.update_configurable_tasks()
+ event_stream(type='task')
if sonarr_changed:
from signalr_client import sonarr_signalr_client
diff --git a/bazarr/database.py b/bazarr/database.py
index 85f420110..03ce0756b 100644
--- a/bazarr/database.py
+++ b/bazarr/database.py
@@ -136,6 +136,8 @@ class TableLanguagesProfiles(BaseModel):
items = TextField()
name = TextField()
profileId = AutoField()
+ mustContain = TextField(null=True)
+ mustNotContain = TextField(null=True)
class Meta:
table_name = 'table_languages_profiles'
@@ -329,7 +331,9 @@ def migrate_db():
migrator.add_column('table_history_movie', 'provider', TextField(null=True)),
migrator.add_column('table_history_movie', 'score', TextField(null=True)),
migrator.add_column('table_history_movie', 'subs_id', TextField(null=True)),
- migrator.add_column('table_history_movie', 'subtitles_path', TextField(null=True))
+ migrator.add_column('table_history_movie', 'subtitles_path', TextField(null=True)),
+ migrator.add_column('table_languages_profiles', 'mustContain', TextField(null=True)),
+ migrator.add_column('table_languages_profiles', 'mustNotContain', TextField(null=True)),
)
@@ -386,6 +390,10 @@ def get_exclusion_clause(exclusion_type):
for item in typesList:
where_clause.append((TableShows.seriesType != item))
+ exclude_season_zero = settings.sonarr.getboolean('exclude_season_zero')
+ if exclude_season_zero:
+ where_clause.append((TableEpisodes.season != 0))
+
return where_clause
@@ -394,10 +402,16 @@ def update_profile_id_list():
profile_id_list = TableLanguagesProfiles.select(TableLanguagesProfiles.profileId,
TableLanguagesProfiles.name,
TableLanguagesProfiles.cutoff,
- TableLanguagesProfiles.items).dicts()
+ TableLanguagesProfiles.items,
+ TableLanguagesProfiles.mustContain,
+ TableLanguagesProfiles.mustNotContain).dicts()
profile_id_list = list(profile_id_list)
for profile in profile_id_list:
profile['items'] = json.loads(profile['items'])
+ profile['mustContain'] = ast.literal_eval(profile['mustContain']) if profile['mustContain'] else \
+ profile['mustContain']
+ profile['mustNotContain'] = ast.literal_eval(profile['mustNotContain']) if profile['mustNotContain'] else \
+ profile['mustNotContain']
def get_profiles_list(profile_id=None):
@@ -422,7 +436,7 @@ def get_desired_languages(profile_id):
if profile_id and profile_id != 'null':
for profile in profile_id_list:
- profileId, name, cutoff, items = profile.values()
+ profileId, name, cutoff, items, mustContain, mustNotContain = profile.values()
if profileId == int(profile_id):
languages = [x['language'] for x in items]
break
@@ -438,7 +452,7 @@ def get_profile_id_name(profile_id):
if profile_id and profile_id != 'null':
for profile in profile_id_list:
- profileId, name, cutoff, items = profile.values()
+ profileId, name, cutoff, items, mustContain, mustNotContain = profile.values()
if profileId == int(profile_id):
name_from_id = name
break
@@ -455,7 +469,7 @@ def get_profile_cutoff(profile_id):
if profile_id and profile_id != 'null':
cutoff_language = []
for profile in profile_id_list:
- profileId, name, cutoff, items = profile.values()
+ profileId, name, cutoff, items, mustContain, mustNotContain = profile.values()
if cutoff:
if profileId == int(profile_id):
for item in items:
@@ -498,6 +512,22 @@ def get_audio_profile_languages(series_id=None, episode_id=None, movie_id=None):
return audio_languages
+def get_profile_id(series_id=None, episode_id=None, movie_id=None):
+ if series_id:
+ profileId = TableShows.get(TableShows.sonarrSeriesId == series_id).profileId
+ elif episode_id:
+ profileId = TableShows.select(TableShows.profileId)\
+ .join(TableEpisodes, on=(TableShows.sonarrSeriesId == TableEpisodes.sonarrSeriesId))\
+ .where(TableEpisodes.sonarrEpisodeId == episode_id)\
+ .get().profileId
+ elif movie_id:
+ profileId = TableMovies.get(TableMovies.radarrId == movie_id).profileId
+ else:
+ return None
+
+ return profileId
+
+
def convert_list_to_clause(arr: list):
if isinstance(arr, list):
return f"({','.join(str(x) for x in arr)})"
diff --git a/bazarr/get_providers.py b/bazarr/get_providers.py
index ab3974c4b..fd21cd380 100644
--- a/bazarr/get_providers.py
+++ b/bazarr/get_providers.py
@@ -8,11 +8,11 @@ import pretty
import time
import socket
import requests
-import ast
from get_args import args
from config import settings, get_array_from
from event_handler import event_stream
+from utils import get_binary
from subliminal_patch.exceptions import TooManyRequests, APIThrottled, ParseResponseError, IPAddressBlocked
from subliminal.providers.opensubtitles import DownloadLimitReached
from subliminal.exceptions import DownloadLimitExceeded, ServiceUnavailable
@@ -126,6 +126,7 @@ def get_providers_auth():
'addic7ed' : {
'username': settings.addic7ed.username,
'password': settings.addic7ed.password,
+ 'is_vip': settings.addic7ed.getboolean('vip'),
},
'opensubtitles' : {
'username' : settings.opensubtitles.username,
@@ -198,6 +199,13 @@ def get_providers_auth():
'email': settings.ktuvit.email,
'hashed_password': settings.ktuvit.hashed_password,
},
+ 'embeddedsubtitles': {
+ 'include_ass': settings.embeddedsubtitles.getboolean('include_ass'),
+ 'include_srt': settings.embeddedsubtitles.getboolean('include_srt'),
+ 'cache_dir': os.path.join(args.config_dir, "cache"),
+ 'ffprobe_path': get_binary("ffprobe"),
+ 'ffmpeg_path': get_binary("ffmpeg"),
+ }
}
@@ -315,12 +323,17 @@ def reset_throttled_providers():
def get_throttled_providers():
providers = {}
- if os.path.exists(os.path.join(args.config_dir, 'config', 'throttled_providers.dat')):
- with open(os.path.normpath(os.path.join(args.config_dir, 'config', 'throttled_providers.dat')), 'r') as handle:
- providers = handle.read()
- if not providers:
- providers = {}
- return providers
+ try:
+ if os.path.exists(os.path.join(args.config_dir, 'config', 'throttled_providers.dat')):
+ with open(os.path.normpath(os.path.join(args.config_dir, 'config', 'throttled_providers.dat')), 'r') as \
+ handle:
+ providers = eval(handle.read())
+ except:
+ # set empty content in throttled_providers.dat
+ logging.error("Invalid content in throttled_providers.dat. Resetting")
+ set_throttled_providers(providers)
+ finally:
+ return providers
def set_throttled_providers(data):
@@ -328,12 +341,6 @@ def set_throttled_providers(data):
handle.write(data)
-try:
- tp = eval(str(get_throttled_providers()))
- if not isinstance(tp, dict):
- raise ValueError('tp should be a dict')
-except Exception:
- logging.error("Invalid content in throttled_providers.dat. Resetting")
- # set empty content in throttled_providers.dat
- set_throttled_providers('')
- tp = eval(str(get_throttled_providers()))
+tp = get_throttled_providers()
+if not isinstance(tp, dict):
+ raise ValueError('tp should be a dict')
diff --git a/bazarr/get_series.py b/bazarr/get_series.py
index c92af286b..9d95e6100 100644
--- a/bazarr/get_series.py
+++ b/bazarr/get_series.py
@@ -117,10 +117,10 @@ def update_series(send_event=True):
logging.debug('BAZARR unable to insert this series into the database:',
path_mappings.path_replace(added_series['path']))
- if send_event:
- event_stream(type='series', action='update', payload=added_series['sonarrSeriesId'])
+ if send_event:
+ event_stream(type='series', action='update', payload=added_series['sonarrSeriesId'])
- logging.debug('BAZARR All series synced from Sonarr into database.')
+ logging.debug('BAZARR All series synced from Sonarr into database.')
def update_one_series(series_id, action):
diff --git a/bazarr/get_subtitle.py b/bazarr/get_subtitle.py
index 9bf0875f9..fcf69bc14 100644
--- a/bazarr/get_subtitle.py
+++ b/bazarr/get_subtitle.py
@@ -84,7 +84,7 @@ def get_video(path, title, sceneName, providers=None, media_type="movie"):
def download_subtitle(path, language, audio_language, hi, forced, providers, providers_auth, sceneName, title,
- media_type, forced_minimum_score=None, is_upgrade=False):
+ media_type, forced_minimum_score=None, is_upgrade=False, profile_id=None):
# fixme: supply all missing languages, not only one, to hit providers only once who support multiple languages in
# one query
@@ -158,6 +158,7 @@ def download_subtitle(path, language, audio_language, hi, forced, providers, pro
compute_score=compute_score,
throttle_time=None, # fixme
blacklist=get_blacklist(media_type=media_type),
+ ban_list=get_ban_list(profile_id),
throttle_callback=provider_throttle,
score_obj=handler,
pre_download_hook=None, # fixme
@@ -216,6 +217,7 @@ def download_subtitle(path, language, audio_language, hi, forced, providers, pro
action = "upgraded"
else:
action = "downloaded"
+
percent_score = round(subtitle.score * 100 / max_score, 2)
message = downloaded_language + modifier_string + " subtitles " + action + " from " + \
downloaded_provider + " with a score of " + str(percent_score) + "%."
@@ -229,6 +231,7 @@ def download_subtitle(path, language, audio_language, hi, forced, providers, pro
series_id = episode_metadata['sonarrSeriesId']
episode_id = episode_metadata['sonarrEpisodeId']
sync_subtitles(video_path=path, srt_path=downloaded_path,
+ forced=subtitle.language.forced,
srt_lang=downloaded_language_code2, media_type=media_type,
percent_score=percent_score,
sonarr_series_id=episode_metadata['sonarrSeriesId'],
@@ -241,6 +244,7 @@ def download_subtitle(path, language, audio_language, hi, forced, providers, pro
series_id = ""
episode_id = movie_metadata['radarrId']
sync_subtitles(video_path=path, srt_path=downloaded_path,
+ forced=subtitle.language.forced,
srt_lang=downloaded_language_code2, media_type=media_type,
percent_score=percent_score,
radarr_id=movie_metadata['radarrId'])
@@ -358,6 +362,7 @@ def manual_search(path, profileId, providers, providers_auth, sceneName, title,
providers=providers,
provider_configs=providers_auth,
blacklist=get_blacklist(media_type=media_type),
+ ban_list=get_ban_list(profileId),
throttle_callback=provider_throttle,
language_hook=None) # fixme
@@ -372,6 +377,7 @@ def manual_search(path, profileId, providers, providers_auth, sceneName, title,
providers=['subscene'],
provider_configs=providers_auth,
blacklist=get_blacklist(media_type=media_type),
+ ban_list=get_ban_list(profileId),
throttle_callback=provider_throttle,
language_hook=None) # fixme
providers_auth['subscene']['only_foreign'] = False
@@ -415,9 +421,10 @@ def manual_search(path, profileId, providers, providers_auth, sceneName, title,
score, score_without_hash = compute_score(matches, s, video, hearing_impaired=initial_hi, score_obj=handler)
if 'hash' not in matches:
not_matched = scores - matches
+ s.score = score_without_hash
else:
+ s.score = score
not_matched = set()
- s.score = score_without_hash
if s.hearing_impaired == initial_hi:
matches.add('hearing_impaired')
@@ -462,7 +469,7 @@ def manual_search(path, profileId, providers, providers_auth, sceneName, title,
def manual_download_subtitle(path, language, audio_language, hi, forced, subtitle, provider, providers_auth, sceneName,
- title, media_type):
+ title, media_type, profile_id):
logging.debug('BAZARR Manually downloading Subtitles for this file: ' + path)
if settings.general.getboolean('utf8_encode'):
@@ -494,6 +501,7 @@ def manual_download_subtitle(path, language, audio_language, hi, forced, subtitl
provider_configs=providers_auth,
pool_class=provider_pool(),
blacklist=get_blacklist(media_type=media_type),
+ ban_list=get_ban_list(profile_id),
throttle_callback=provider_throttle)
logging.debug('BAZARR Subtitles file downloaded for this file:' + path)
else:
@@ -552,6 +560,7 @@ def manual_download_subtitle(path, language, audio_language, hi, forced, subtitl
series_id = episode_metadata['sonarrSeriesId']
episode_id = episode_metadata['sonarrEpisodeId']
sync_subtitles(video_path=path, srt_path=downloaded_path,
+ forced=subtitle.language.forced,
srt_lang=downloaded_language_code2, media_type=media_type,
percent_score=score,
sonarr_series_id=episode_metadata['sonarrSeriesId'],
@@ -564,6 +573,7 @@ def manual_download_subtitle(path, language, audio_language, hi, forced, subtitl
series_id = ""
episode_id = movie_metadata['radarrId']
sync_subtitles(video_path=path, srt_path=downloaded_path,
+ forced=subtitle.language.forced,
srt_lang=downloaded_language_code2, media_type=media_type,
percent_score=score, radarr_id=movie_metadata['radarrId'])
@@ -696,7 +706,7 @@ def manual_upload_subtitle(path, language, forced, hi, title, scene_name, media_
series_id = episode_metadata['sonarrSeriesId']
episode_id = episode_metadata['sonarrEpisodeId']
sync_subtitles(video_path=path, srt_path=subtitle_path, srt_lang=uploaded_language_code2, media_type=media_type,
- percent_score=100, sonarr_series_id=episode_metadata['sonarrSeriesId'],
+ percent_score=100, sonarr_series_id=episode_metadata['sonarrSeriesId'], forced=forced,
sonarr_episode_id=episode_metadata['sonarrEpisodeId'])
else:
movie_metadata = TableMovies.select(TableMovies.radarrId)\
@@ -706,7 +716,7 @@ def manual_upload_subtitle(path, language, forced, hi, title, scene_name, media_
series_id = ""
episode_id = movie_metadata['radarrId']
sync_subtitles(video_path=path, srt_path=subtitle_path, srt_lang=uploaded_language_code2, media_type=media_type,
- percent_score=100, radarr_id=movie_metadata['radarrId'])
+ percent_score=100, radarr_id=movie_metadata['radarrId'], forced=forced)
if use_postprocessing :
command = pp_replace(postprocessing_cmd, path, subtitle_path, uploaded_language,
@@ -755,12 +765,13 @@ def series_download_subtitles(no):
"ignored because of monitored status, series type or series tags: {}".format(no))
return
- providers_list = get_providers()
providers_auth = get_providers_auth()
count_episodes_details = len(episodes_details)
for i, episode in enumerate(episodes_details):
+ providers_list = get_providers()
+
if providers_list:
show_progress(id='series_search_progress_{}'.format(no),
header='Searching missing subtitles...',
@@ -845,10 +856,11 @@ def episode_download_subtitles(no, send_progress=False):
logging.debug("BAZARR no episode with that sonarrEpisodeId can be found in database:", str(no))
return
- providers_list = get_providers()
providers_auth = get_providers_auth()
for episode in episodes_details:
+ providers_list = get_providers()
+
if providers_list:
if send_progress:
show_progress(id='episode_search_progress_{}'.format(no),
@@ -929,7 +941,6 @@ def movies_download_subtitles(no):
else:
movie = movies[0]
- providers_list = get_providers()
providers_auth = get_providers_auth()
if ast.literal_eval(movie['missing_subtitles']):
@@ -938,15 +949,17 @@ def movies_download_subtitles(no):
count_movie = 0
for i, language in enumerate(ast.literal_eval(movie['missing_subtitles'])):
- # confirm if language is still missing or if cutoff have been reached
- confirmed_missing_subs = TableMovies.select(TableMovies.missing_subtitles)\
- .where(TableMovies.radarrId == movie['radarrId'])\
- .dicts()\
- .get()
- if language not in ast.literal_eval(confirmed_missing_subs['missing_subtitles']):
- continue
+ providers_list = get_providers()
if providers_list:
+ # confirm if language is still missing or if cutoff have been reached
+ confirmed_missing_subs = TableMovies.select(TableMovies.missing_subtitles) \
+ .where(TableMovies.radarrId == movie['radarrId']) \
+ .dicts() \
+ .get()
+ if language not in ast.literal_eval(confirmed_missing_subs['missing_subtitles']):
+ continue
+
show_progress(id='movie_search_progress_{}'.format(no),
header='Searching missing subtitles...',
name=movie['title'],
@@ -1008,77 +1021,71 @@ def wanted_download_subtitles(sonarr_episode_id):
.dicts()
episodes_details = list(episodes_details)
- providers_list = get_providers()
providers_auth = get_providers_auth()
for episode in episodes_details:
- attempt = episode['failedAttempts']
- if type(attempt) == str:
- attempt = ast.literal_eval(attempt)
- for language in ast.literal_eval(episode['missing_subtitles']):
- # confirm if language is still missing or if cutoff have been reached
- confirmed_missing_subs = TableEpisodes.select(TableEpisodes.missing_subtitles) \
- .where(TableEpisodes.sonarrEpisodeId == episode['sonarrEpisodeId']) \
- .dicts() \
- .get()
- if language not in ast.literal_eval(confirmed_missing_subs['missing_subtitles']):
- continue
+ providers_list = get_providers()
- if attempt is None:
- attempt = []
- attempt.append([language, time.time()])
- else:
- att = list(zip(*attempt))[0]
- if language not in att:
- attempt.append([language, time.time()])
+ if providers_list:
+ for language in ast.literal_eval(episode['missing_subtitles']):
+ # confirm if language is still missing or if cutoff have been reached
+ confirmed_missing_subs = TableEpisodes.select(TableEpisodes.missing_subtitles) \
+ .where(TableEpisodes.sonarrEpisodeId == episode['sonarrEpisodeId']) \
+ .dicts() \
+ .get()
+ if language not in ast.literal_eval(confirmed_missing_subs['missing_subtitles']):
+ continue
- TableEpisodes.update({TableEpisodes.failedAttempts: str(attempt)})\
- .where(TableEpisodes.sonarrEpisodeId == episode['sonarrEpisodeId'])\
- .execute()
+ if is_search_active(desired_language=language, attempt_string=episode['failedAttempts']):
+ TableEpisodes.update({TableEpisodes.failedAttempts:
+ updateFailedAttempts(desired_language=language,
+ attempt_string=episode['failedAttempts'])}) \
+ .where(TableEpisodes.sonarrEpisodeId == episode['sonarrEpisodeId']) \
+ .execute()
- for i in range(len(attempt)):
- if attempt[i][0] == language:
- if search_active(attempt[i][1]):
- audio_language_list = get_audio_profile_languages(episode_id=episode['sonarrEpisodeId'])
- if len(audio_language_list) > 0:
- audio_language = audio_language_list[0]['name']
- else:
- audio_language = 'None'
-
- result = download_subtitle(path_mappings.path_replace(episode['path']),
- language.split(':')[0],
- audio_language,
- "True" if language.endswith(':hi') else "False",
- "True" if language.endswith(':forced') else "False",
- providers_list,
- providers_auth,
- str(episode['scene_name']),
- episode['title'],
- 'series')
- if result is not None:
- message = result[0]
- path = result[1]
- forced = result[5]
- if result[8]:
- language_code = result[2] + ":hi"
- elif forced:
- language_code = result[2] + ":forced"
- else:
- language_code = result[2]
- provider = result[3]
- score = result[4]
- subs_id = result[6]
- subs_path = result[7]
- store_subtitles(episode['path'], path_mappings.path_replace(episode['path']))
- history_log(1, episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message, path,
- language_code, provider, score, subs_id, subs_path)
- event_stream(type='series', action='update', payload=episode['sonarrSeriesId'])
- event_stream(type='episode-wanted', action='delete', payload=episode['sonarrEpisodeId'])
- send_notifications(episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message)
+ audio_language_list = get_audio_profile_languages(episode_id=episode['sonarrEpisodeId'])
+ if len(audio_language_list) > 0:
+ audio_language = audio_language_list[0]['name']
else:
- logging.debug(
- 'BAZARR Search is not active for episode ' + episode['path'] + ' Language: ' + attempt[i][
- 0])
+ audio_language = 'None'
+
+ result = download_subtitle(path_mappings.path_replace(episode['path']),
+ language.split(':')[0],
+ audio_language,
+ "True" if language.endswith(':hi') else "False",
+ "True" if language.endswith(':forced') else "False",
+ providers_list,
+ providers_auth,
+ str(episode['scene_name']),
+ episode['title'],
+ 'series')
+ if result is not None:
+ message = result[0]
+ path = result[1]
+ forced = result[5]
+ if result[8]:
+ language_code = result[2] + ":hi"
+ elif forced:
+ language_code = result[2] + ":forced"
+ else:
+ language_code = result[2]
+ provider = result[3]
+ score = result[4]
+ subs_id = result[6]
+ subs_path = result[7]
+ store_subtitles(episode['path'], path_mappings.path_replace(episode['path']))
+ history_log(1, episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message, path,
+ language_code, provider, score, subs_id, subs_path)
+ event_stream(type='series', action='update', payload=episode['sonarrSeriesId'])
+ event_stream(type='episode-wanted', action='delete', payload=episode['sonarrEpisodeId'])
+ send_notifications(episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message)
+ else:
+ logging.debug(
+ f"BAZARR Search is throttled by adaptive search for this episode {episode['path']} and "
+ f"language: {language}")
+ else:
+ logging.info("BAZARR All providers are throttled")
+ break
def wanted_download_subtitles_movie(radarr_id):
@@ -1093,76 +1100,69 @@ def wanted_download_subtitles_movie(radarr_id):
.dicts()
movies_details = list(movies_details)
- providers_list = get_providers()
providers_auth = get_providers_auth()
for movie in movies_details:
- attempt = movie['failedAttempts']
- if type(attempt) == str:
- attempt = ast.literal_eval(attempt)
- for language in ast.literal_eval(movie['missing_subtitles']):
- # confirm if language is still missing or if cutoff have been reached
- confirmed_missing_subs = TableMovies.select(TableMovies.missing_subtitles) \
- .where(TableMovies.radarrId == movie['radarrId']) \
- .dicts() \
- .get()
- if language not in ast.literal_eval(confirmed_missing_subs['missing_subtitles']):
- continue
+ providers_list = get_providers()
- if attempt is None:
- attempt = []
- attempt.append([language, time.time()])
- else:
- att = list(zip(*attempt))[0]
- if language not in att:
- attempt.append([language, time.time()])
+ if providers_list:
+ for language in ast.literal_eval(movie['missing_subtitles']):
+ # confirm if language is still missing or if cutoff have been reached
+ confirmed_missing_subs = TableMovies.select(TableMovies.missing_subtitles) \
+ .where(TableMovies.radarrId == movie['radarrId']) \
+ .dicts() \
+ .get()
+ if language not in ast.literal_eval(confirmed_missing_subs['missing_subtitles']):
+ continue
- TableMovies.update({TableMovies.failedAttempts: str(attempt)})\
- .where(TableMovies.radarrId == movie['radarrId'])\
- .execute()
+ if is_search_active(desired_language=language, attempt_string=movie['failedAttempts']):
+ TableMovies.update({TableMovies.failedAttempts:
+ updateFailedAttempts(desired_language=language,
+ attempt_string=movie['failedAttempts'])}) \
+ .where(TableMovies.radarrId == movie['radarrId']) \
+ .execute()
- for i in range(len(attempt)):
- if attempt[i][0] == language:
- if search_active(attempt[i][1]) is True:
- audio_language_list = get_audio_profile_languages(movie_id=movie['radarrId'])
- if len(audio_language_list) > 0:
- audio_language = audio_language_list[0]['name']
- else:
- audio_language = 'None'
-
- result = download_subtitle(path_mappings.path_replace_movie(movie['path']),
- language.split(':')[0],
- audio_language,
- "True" if language.endswith(':hi') else "False",
- "True" if language.endswith(':forced') else "False",
- providers_list,
- providers_auth,
- str(movie['sceneName']),
- movie['title'],
- 'movie')
- if result is not None:
- message = result[0]
- path = result[1]
- forced = result[5]
- if result[8]:
- language_code = result[2] + ":hi"
- elif forced:
- language_code = result[2] + ":forced"
- else:
- language_code = result[2]
- provider = result[3]
- score = result[4]
- subs_id = result[6]
- subs_path = result[7]
- store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']))
- history_log_movie(1, movie['radarrId'], message, path, language_code, provider, score,
- subs_id, subs_path)
- event_stream(type='movie-wanted', action='delete', payload=movie['radarrId'])
- send_notifications_movie(movie['radarrId'], message)
+ audio_language_list = get_audio_profile_languages(movie_id=movie['radarrId'])
+ if len(audio_language_list) > 0:
+ audio_language = audio_language_list[0]['name']
else:
- logging.info(
- 'BAZARR Search is not active for this Movie ' + movie['path'] + ' Language: ' + attempt[i][
- 0])
+ audio_language = 'None'
+
+ result = download_subtitle(path_mappings.path_replace_movie(movie['path']),
+ language.split(':')[0],
+ audio_language,
+ "True" if language.endswith(':hi') else "False",
+ "True" if language.endswith(':forced') else "False",
+ providers_list,
+ providers_auth,
+ str(movie['sceneName']),
+ movie['title'],
+ 'movie')
+ if result is not None:
+ message = result[0]
+ path = result[1]
+ forced = result[5]
+ if result[8]:
+ language_code = result[2] + ":hi"
+ elif forced:
+ language_code = result[2] + ":forced"
+ else:
+ language_code = result[2]
+ provider = result[3]
+ score = result[4]
+ subs_id = result[6]
+ subs_path = result[7]
+ store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']))
+ history_log_movie(1, movie['radarrId'], message, path, language_code, provider, score,
+ subs_id, subs_path)
+ event_stream(type='movie-wanted', action='delete', payload=movie['radarrId'])
+ send_notifications_movie(movie['radarrId'], message)
+ else:
+ logging.info(f"BAZARR Search is throttled by adaptive search for this movie {movie['path']} and "
+ f"language: {language}")
+ else:
+ logging.info("BAZARR All providers are throttled")
+ break
def wanted_search_missing_subtitles_series():
@@ -1236,25 +1236,6 @@ def wanted_search_missing_subtitles_movies():
logging.info('BAZARR Finished searching for missing Movies Subtitles. Check History for more information.')
-def search_active(timestamp):
- if settings.general.getboolean('adaptive_searching'):
- search_deadline = timedelta(weeks=3)
- search_delta = timedelta(weeks=1)
- aa = datetime.fromtimestamp(float(timestamp))
- attempt_datetime = datetime.strptime(str(aa).split(".")[0], '%Y-%m-%d %H:%M:%S')
- attempt_search_deadline = attempt_datetime + search_deadline
- today = datetime.today()
- attempt_age_in_days = (today.date() - attempt_search_deadline.date()).days
- if today.date() <= attempt_search_deadline.date():
- return True
- elif attempt_age_in_days % search_delta.days == 0:
- return True
- else:
- return False
- else:
- return True
-
-
def convert_to_guessit(guessit_key, attr_from_db):
try:
return guessit(attr_from_db)[guessit_key]
@@ -1490,11 +1471,12 @@ def upgrade_subtitles():
count_movie_to_upgrade = len(movies_to_upgrade)
- providers_list = get_providers()
providers_auth = get_providers_auth()
if settings.general.getboolean('use_sonarr'):
for i, episode in enumerate(episodes_to_upgrade):
+ providers_list = get_providers()
+
show_progress(id='upgrade_episodes_progress',
header='Upgrading episodes subtitles...',
name='{0} - S{1:02d}E{2:02d} - {3}'.format(episode['seriesTitle'],
@@ -1504,8 +1486,7 @@ def upgrade_subtitles():
value=i,
count=count_episode_to_upgrade)
- providers = get_providers()
- if not providers:
+ if not providers_list:
logging.info("BAZARR All providers are throttled")
return
if episode['language'].endswith('forced'):
@@ -1562,17 +1543,15 @@ def upgrade_subtitles():
if settings.general.getboolean('use_radarr'):
for i, movie in enumerate(movies_to_upgrade):
+ providers_list = get_providers()
+
show_progress(id='upgrade_movies_progress',
header='Upgrading movies subtitles...',
name=movie['title'],
value=i,
count=count_movie_to_upgrade)
- providers = get_providers()
- if not providers:
- logging.info("BAZARR All providers are throttled")
- return
- if not providers:
+ if not providers_list:
logging.info("BAZARR All providers are throttled")
return
if movie['language'].endswith('forced'):
@@ -1660,9 +1639,15 @@ def postprocessing(command, path):
logging.info('BAZARR Post-processing result for file ' + path + ' : ' + out)
-def sync_subtitles(video_path, srt_path, srt_lang, media_type, percent_score, sonarr_series_id=None,
+def sync_subtitles(video_path, srt_path, srt_lang, forced, media_type, percent_score, sonarr_series_id=None,
sonarr_episode_id=None, radarr_id=None):
- if settings.subsync.getboolean('use_subsync'):
+ if forced:
+ logging.debug('BAZARR cannot sync forced subtitles. Skipping sync routine.')
+ elif not settings.subsync.getboolean('use_subsync'):
+ logging.debug('BAZARR automatic syncing is disabled in settings. Skipping sync routine.')
+ else:
+ logging.debug(f'BAZARR automatic syncing is enabled in settings. We\'ll try to sync this '
+ f'subtitles: {srt_path}.')
if media_type == 'series':
use_subsync_threshold = settings.subsync.getboolean('use_subsync_threshold')
subsync_threshold = settings.subsync.subsync_threshold
@@ -1694,6 +1679,7 @@ def _get_lang_obj(alpha3):
return sub.subzero_language()
+
def _get_scores(media_type, min_movie=None, min_ep=None):
series = "series" == media_type
handler = series_score if series else movie_score
@@ -1701,3 +1687,154 @@ def _get_scores(media_type, min_movie=None, min_ep=None):
min_ep = min_ep or (240 * 100 / handler.max_score)
min_score_ = int(min_ep if series else min_movie)
return handler.get_scores(min_score_)
+
+
+def get_ban_list(profile_id):
+ if profile_id:
+ profile = get_profiles_list(profile_id)
+ if profile:
+ return {'must_contain': profile['mustContain'] or [],
+ 'must_not_contain': profile['mustNotContain'] or []}
+ return None
+
+
+def is_search_active(desired_language, attempt_string):
+ """
+ Function to test if it's time to search again after a previous attempt matching the desired language. For 3 weeks,
+ we search on a scheduled basis but after 3 weeks we start searching only once a week.
+
+ @param desired_language: 2 letters language to search for in attempts
+ @type desired_language: str
+ @param attempt_string: string representation of a list of lists from database column failedAttempts
+ @type attempt_string: str
+
+ @return: return True if it's time to search again and False if not
+ @rtype: bool
+ """
+
+ if settings.general.getboolean('adaptive_searching'):
+ logging.debug("Adaptive searching is enable, we'll see if it's time to search again...")
+ try:
+ # let's try to get a list of lists from the string representation in database
+ attempts = ast.literal_eval(attempt_string)
+ if type(attempts) is not list:
+ # attempts should be a list if not, it's malformed or None
+ raise ValueError
+ except ValueError:
+ logging.debug("Adaptive searching: attempts is malformed. As a failsafe, search will run.")
+ return True
+
+ if not len(attempts):
+ logging.debug("Adaptive searching: attempts list is empty, search will run.")
+ return True
+
+ # get attempts matching the desired language and sort them by timestamp ascending
+ matching_attempts = sorted([x for x in attempts if x[0] == desired_language], key=lambda x: x[1])
+
+ if not len(matching_attempts):
+ logging.debug("Adaptive searching: there's no attempts matching desired language, search will run.")
+ return True
+ else:
+ logging.debug(f"Adaptive searching: attempts matching language {desired_language}: {matching_attempts}")
+
+ # try to get the initial and latest search timestamp from matching attempts
+ initial_search_attempt = matching_attempts[0]
+ latest_search_attempt = matching_attempts[-1]
+
+ # try to parse the timestamps for those attempts
+ try:
+ initial_search_timestamp = datetime.fromtimestamp(initial_search_attempt[1])
+ latest_search_timestamp = datetime.fromtimestamp(latest_search_attempt[1])
+ except (OverflowError, ValueError, OSError):
+ logging.debug("Adaptive searching: unable to parse initial and latest search timestamps, search will run.")
+ return True
+ else:
+ logging.debug(f"Adaptive searching: initial search date for {desired_language} is "
+ f"{initial_search_timestamp}")
+ logging.debug(f"Adaptive searching: latest search date for {desired_language} is {latest_search_timestamp}")
+
+ # defining basic calculation variables
+ now = datetime.now()
+ if settings.general.adaptive_searching_delay.endswith('d'):
+ extended_search_delay = timedelta(days=int(settings.general.adaptive_searching_delay[:1]))
+ elif settings.general.adaptive_searching_delay.endswith('w'):
+ extended_search_delay = timedelta(weeks=int(settings.general.adaptive_searching_delay[:1]))
+ else:
+ logging.debug(f"Adaptive searching: cannot parse adaptive_searching_delay from config file: "
+ f"{settings.general.adaptive_searching_delay}")
+ return True
+ logging.debug(f"Adaptive searching: delay after initial search value: {extended_search_delay}")
+
+ if settings.general.adaptive_searching_delta.endswith('d'):
+ extended_search_delta = timedelta(days=int(settings.general.adaptive_searching_delta[:1]))
+ elif settings.general.adaptive_searching_delta.endswith('w'):
+ extended_search_delta = timedelta(weeks=int(settings.general.adaptive_searching_delta[:1]))
+ else:
+ logging.debug(f"Adaptive searching: cannot parse adaptive_searching_delta from config file: "
+ f"{settings.general.adaptive_searching_delta}")
+ return True
+ logging.debug(f"Adaptive searching: delta between latest search and now value: {extended_search_delta}")
+
+ if initial_search_timestamp + extended_search_delay > now:
+ logging.debug(f"Adaptive searching: it's been less than {settings.general.adaptive_searching_delay} since "
+ f"initial search, search will run.")
+ return True
+ else:
+ logging.debug(f"Adaptive searching: it's been more than {settings.general.adaptive_searching_delay} since "
+ f"initial search, let's check if it's time to search again.")
+ if latest_search_timestamp + extended_search_delta <= now:
+ logging.debug(
+ f"Adaptive searching: it's been more than {settings.general.adaptive_searching_delta} since "
+ f"latest search, search will run.")
+ return True
+ else:
+ logging.debug(
+ f"Adaptive searching: it's been less than {settings.general.adaptive_searching_delta} since "
+ f"latest search, we're not ready to search yet.")
+ return False
+
+ logging.debug("adaptive searching is disabled, search will run.")
+ return True
+
+
+def updateFailedAttempts(desired_language, attempt_string):
+ """
+ Function to parse attempts and make sure we only keep initial and latest search timestamp for each language.
+
+ @param desired_language: 2 letters language to search for in attempts
+ @type desired_language: str
+ @param attempt_string: string representation of a list of lists from database column failedAttempts
+ @type attempt_string: str
+
+ @return: return a string representation of a list of lists like [str(language_code), str(attempts)]
+ @rtype: str
+ """
+
+ try:
+ # let's try to get a list of lists from the string representation in database
+ attempts = ast.literal_eval(attempt_string)
+ logging.debug(f"Adaptive searching: current attempts value is {attempts}")
+ if type(attempts) is not list:
+ # attempts should be a list if not, it's malformed or None
+ raise ValueError
+ except ValueError:
+ logging.debug("Adaptive searching: failed to parse attempts value, we'll use an empty list.")
+ attempts = []
+
+ matching_attempts = sorted([x for x in attempts if x[0] == desired_language], key=lambda x: x[1])
+ logging.debug(f"Adaptive searching: attempts matching language {desired_language}: {matching_attempts}")
+
+ filtered_attempts = sorted([x for x in attempts if x[0] != desired_language], key=lambda x: x[1])
+ logging.debug(f"Adaptive searching: attempts not matching language {desired_language}: {filtered_attempts}")
+
+ # get the initial search from attempts if there's one
+ if len(matching_attempts):
+ filtered_attempts.append(matching_attempts[0])
+
+ # append current attempt with language and timestamp to attempts
+ filtered_attempts.append([desired_language, datetime.timestamp(datetime.now())])
+
+ updated_attempts = sorted(filtered_attempts, key=lambda x: x[0])
+ logging.debug(f"Adaptive searching: updated attempts that will be saved to database is {updated_attempts}")
+
+ return str(updated_attempts)
diff --git a/bazarr/notifier.py b/bazarr/notifier.py
index c409eef45..7a24303ee 100644
--- a/bazarr/notifier.py
+++ b/bazarr/notifier.py
@@ -23,11 +23,11 @@ def update_notifier():
notifiers_current.append([notifier['name']])
for x in results['schemas']:
- if [x['service_name']] not in notifiers_current:
- notifiers_new.append({'name': x['service_name'], 'enabled': 0})
- logging.debug('Adding new notifier agent: ' + x['service_name'])
+ if [str(x['service_name'])] not in notifiers_current:
+ notifiers_new.append({'name': str(x['service_name']), 'enabled': 0})
+ logging.debug('Adding new notifier agent: ' + str(x['service_name']))
else:
- notifiers_old.append([x['service_name']])
+ notifiers_old.append([str(x['service_name'])])
notifiers_to_delete = [item for item in notifiers_current if item not in notifiers_old]
diff --git a/bazarr/score.py b/bazarr/score.py
index 09b568a30..612e63df7 100644
--- a/bazarr/score.py
+++ b/bazarr/score.py
@@ -146,6 +146,7 @@ class Score:
def __init__(self, load_profiles=False, **kwargs):
self.data = self.defaults.copy()
self.data.update(**kwargs)
+ self.data["hash"] = self._hash_score()
self._profiles = []
self._profiles_loaded = False
@@ -205,9 +206,16 @@ class Score:
@property
def max_score(self):
return (
- sum(val for val in self.scores.values() if val > 0)
- + sum(item.score for item in self._profiles if item.score > 0)
- - self.data["hash"]
+ self.data["hash"]
+ + self.data["hearing_impaired"]
+ + sum(item.score for item in self._profiles if item.score)
+ )
+
+ def _hash_score(self):
+ return sum(
+ val
+ for key, val in self.data.items()
+ if key not in ("hash", "hearing_impaired")
)
def __str__(self):
diff --git a/bazarr/server.py b/bazarr/server.py
index b414d8ee6..0b024d1ec 100644
--- a/bazarr/server.py
+++ b/bazarr/server.py
@@ -13,8 +13,9 @@ from database import database
from app import create_app
app = create_app()
-from api import api_bp
-app.register_blueprint(api_bp)
+from api import api_bp_list
+for item in api_bp_list:
+ app.register_blueprint(item, url_prefix=base_url.rstrip('/') + '/api')
class Server:
diff --git a/bazarr/signalr_client.py b/bazarr/signalr_client.py
index f8c3c7e8f..9eb57dafb 100644
--- a/bazarr/signalr_client.py
+++ b/bazarr/signalr_client.py
@@ -22,9 +22,9 @@ from get_args import args
headers = {"User-Agent": os.environ["SZ_USER_AGENT"]}
-class SonarrSignalrClient:
+class SonarrSignalrClientLegacy:
def __init__(self):
- super(SonarrSignalrClient, self).__init__()
+ super(SonarrSignalrClientLegacy, self).__init__()
self.apikey_sonarr = None
self.session = Session()
self.session.timeout = 60
@@ -92,6 +92,65 @@ class SonarrSignalrClient:
self.connection.exception += self.exception_handler
+class SonarrSignalrClient:
+ def __init__(self):
+ super(SonarrSignalrClient, self).__init__()
+ self.apikey_sonarr = None
+ self.connection = None
+
+ def start(self):
+ self.configure()
+ logging.info('BAZARR trying to connect to Sonarr SignalR feed...')
+ while self.connection.transport.state.value not in [0, 1, 2]:
+ try:
+ self.connection.start()
+ except ConnectionError:
+ time.sleep(5)
+
+ def stop(self):
+ logging.info('BAZARR SignalR client for Sonarr is now disconnected.')
+ self.connection.stop()
+
+ def restart(self):
+ if self.connection:
+ if self.connection.transport.state.value in [0, 1, 2]:
+ self.stop()
+ if settings.general.getboolean('use_sonarr'):
+ self.start()
+
+ def exception_handler(self):
+ logging.error("BAZARR connection to Sonarr SignalR feed has failed. We'll try to reconnect.")
+ self.restart()
+
+ @staticmethod
+ def on_connect_handler():
+ logging.info('BAZARR SignalR client for Sonarr is connected and waiting for events.')
+ if not args.dev:
+ scheduler.add_job(update_series, kwargs={'send_event': True}, max_instances=1)
+ scheduler.add_job(sync_episodes, kwargs={'send_event': True}, max_instances=1)
+
+ def configure(self):
+ self.apikey_sonarr = settings.sonarr.apikey
+ self.connection = HubConnectionBuilder() \
+ .with_url(url_sonarr() + "/signalr/messages?access_token={}".format(self.apikey_sonarr),
+ options={
+ "verify_ssl": False,
+ "headers": headers
+ }) \
+ .with_automatic_reconnect({
+ "type": "raw",
+ "keep_alive_interval": 5,
+ "reconnect_interval": 180,
+ "max_attempts": None
+ }).build()
+ self.connection.on_open(self.on_connect_handler)
+ self.connection.on_reconnect(lambda: logging.error('BAZARR SignalR client for Sonarr connection as been lost. '
+ 'Trying to reconnect...'))
+ self.connection.on_close(lambda: logging.debug('BAZARR SignalR client for Sonarr is disconnected.'))
+ self.connection.on_error(self.exception_handler)
+ self.connection.on("receiveMessage", dispatcher)
+
+
class RadarrSignalrClient:
def __init__(self):
super(RadarrSignalrClient, self).__init__()
@@ -186,5 +245,6 @@ def dispatcher(data):
return
-sonarr_signalr_client = SonarrSignalrClient()
+sonarr_signalr_client = SonarrSignalrClientLegacy() if get_sonarr_info.version().startswith(('0.', '2.', '3.')) else \
+ SonarrSignalrClient()
radarr_signalr_client = RadarrSignalrClient()
diff --git a/bazarr/utils.py b/bazarr/utils.py
index dfb1c7799..fa88927bc 100644
--- a/bazarr/utils.py
+++ b/bazarr/utils.py
@@ -256,8 +256,10 @@ class GetSonarrInfo:
if 'version' in sonarr_json:
sonarr_version = sonarr_json['version']
else:
- sv = url_sonarr() + "/api/v3/system/status?apikey=" + settings.sonarr.apikey
- sonarr_version = requests.get(sv, timeout=60, verify=False, headers=headers).json()['version']
+ raise json.decoder.JSONDecodeError
+ except json.decoder.JSONDecodeError:
+ sv = url_sonarr() + "/api/v3/system/status?apikey=" + settings.sonarr.apikey
+ sonarr_version = requests.get(sv, timeout=60, verify=False, headers=headers).json()['version']
except Exception:
logging.debug('BAZARR cannot get Sonarr version')
sonarr_version = 'unknown'
@@ -434,10 +436,14 @@ def subtitles_apply_mods(language, subtitle_path, mods):
def translate_subtitles_file(video_path, source_srt_file, to_lang, forced, hi):
language_code_convert_dict = {
'he': 'iw',
+ 'zt': 'zh-cn',
+ 'zh': 'zh-tw',
}
to_lang = alpha3_from_alpha2(to_lang)
- lang_obj = Language(to_lang)
+ lang_obj = CustomLanguage.from_value(to_lang, "alpha3")
+ if not lang_obj:
+ lang_obj = Language(to_lang)
if forced:
lang_obj = Language.rebuild(lang_obj, forced=True)
if hi:
@@ -447,7 +453,8 @@ def translate_subtitles_file(video_path, source_srt_file, to_lang, forced, hi):
max_characters = 5000
- dest_srt_file = get_subtitle_path(video_path, language=lang_obj, extension='.srt', forced_tag=forced, hi_tag=hi)
+ dest_srt_file = get_subtitle_path(video_path, language=lang_obj if isinstance(lang_obj, Language) else lang_obj.subzero_language(),
+ extension='.srt', forced_tag=forced, hi_tag=hi)
subs = pysubs2.load(source_srt_file, encoding='utf-8')
lines_list = [x.plaintext for x in subs]
@@ -471,8 +478,8 @@ def translate_subtitles_file(video_path, source_srt_file, to_lang, forced, hi):
for block_str in lines_block_list:
try:
translated_partial_srt_text = GoogleTranslator(source='auto',
- target=language_code_convert_dict.get(lang_obj.basename,
- lang_obj.basename)
+ target=language_code_convert_dict.get(lang_obj.alpha2,
+ lang_obj.alpha2)
).translate(text=block_str)
except:
return False
diff --git a/dev-requirements.txt b/dev-requirements.txt
index e812f80b9..9ba4733a1 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -4,3 +4,4 @@ pytest
pytest-pep8
pytest-flakes
pytest-cov
+pytest-vcr
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 879175837..45fe602f6 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -20,7 +20,6 @@
"bootstrap": "^4",
"lodash": "^4",
"moment": "^2.29.1",
- "package.json": "^2.0.1",
"rc-slider": "^9.7",
"react": "^17",
"react-bootstrap": "^1",
@@ -3156,6 +3155,11 @@
"@sinonjs/commons": "^1.7.0"
}
},
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz",
+ "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q=="
+ },
"node_modules/@surma/rollup-plugin-off-main-thread": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz",
@@ -3427,11 +3431,6 @@
"@types/jquery": "*"
}
},
- "node_modules/@types/component-emitter": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
- "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
- },
"node_modules/@types/d3-path": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz",
@@ -3620,9 +3619,9 @@
}
},
"node_modules/@types/react-dom": {
- "version": "17.0.9",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz",
- "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==",
+ "version": "17.0.11",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.11.tgz",
+ "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==",
"dev": true,
"dependencies": {
"@types/react": "*"
@@ -4220,14 +4219,6 @@
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
"integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q=="
},
- "node_modules/abs": {
- "version": "1.3.14",
- "resolved": "https://registry.npmjs.org/abs/-/abs-1.3.14.tgz",
- "integrity": "sha512-PrS26IzwKLWwuURpiKl8wRmJ2KdR/azaVrLEBWG/TALwT20Y7qjtYp1qcMLHA4206hBHY5phv3w4pjf9NPv4Vw==",
- "dependencies": {
- "ul": "^5.0.0"
- }
- },
"node_modules/accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -5353,9 +5344,9 @@
}
},
"node_modules/base64-arraybuffer": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
- "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz",
+ "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==",
"engines": {
"node": ">= 0.6.0"
}
@@ -5891,14 +5882,6 @@
"node": "6.* || 8.* || >= 10.*"
}
},
- "node_modules/capture-stack-trace": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
- "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/case-sensitive-paths-webpack-plugin": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz",
@@ -6580,17 +6563,6 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
},
- "node_modules/create-error-class": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
- "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
- "dependencies": {
- "capture-stack-trace": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
@@ -7216,14 +7188,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -7357,14 +7321,6 @@
"which": "bin/which"
}
},
- "node_modules/deffy": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.4.tgz",
- "integrity": "sha512-pLc9lsbsWjr6RxmJ2OLyvm+9l4j1yK69h+TML/gUit/t3vTijpkNGh8LioaJYTGO7F25m6HZndADcUOo2PsiUg==",
- "dependencies": {
- "typpy": "^2.0.0"
- }
- },
"node_modules/define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -7739,14 +7695,6 @@
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
},
- "node_modules/duplexer2": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
- "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
- "dependencies": {
- "readable-stream": "^2.0.2"
- }
- },
"node_modules/duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -7837,18 +7785,18 @@
}
},
"node_modules/engine.io-client": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-5.1.2.tgz",
- "integrity": "sha512-blRrgXIE0A/eurWXRzvfCLG7uUFJqfTGFsyJzXSK71srMMGJ2VraBLg8Mdw28uUxSpVicepBN9X7asqpD1mZcQ==",
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz",
+ "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==",
"dependencies": {
- "base64-arraybuffer": "0.1.4",
- "component-emitter": "~1.3.0",
+ "@socket.io/component-emitter": "~3.0.0",
"debug": "~4.3.1",
- "engine.io-parser": "~4.0.1",
+ "engine.io-parser": "~5.0.0",
"has-cors": "1.1.0",
"parseqs": "0.0.6",
"parseuri": "0.0.6",
- "ws": "~7.4.2",
+ "ws": "~8.2.3",
+ "xmlhttprequest-ssl": "~2.0.0",
"yeast": "0.1.2"
}
},
@@ -7873,15 +7821,35 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
+ "node_modules/engine.io-client/node_modules/ws": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
+ "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/engine.io-parser": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
- "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.2.tgz",
+ "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==",
"dependencies": {
- "base64-arraybuffer": "0.1.4"
+ "base64-arraybuffer": "~1.0.1"
},
"engines": {
- "node": ">=8.0.0"
+ "node": ">=10.0.0"
}
},
"node_modules/enhanced-resolve": {
@@ -7928,14 +7896,6 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/err": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/err/-/err-1.1.1.tgz",
- "integrity": "sha1-65KOLhGjFmSPeCgz0PlyWLpDwvg=",
- "dependencies": {
- "typpy": "^2.2.0"
- }
- },
"node_modules/errno": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
@@ -9078,15 +9038,6 @@
"safe-buffer": "^5.1.1"
}
},
- "node_modules/exec-limiter": {
- "version": "3.2.13",
- "resolved": "https://registry.npmjs.org/exec-limiter/-/exec-limiter-3.2.13.tgz",
- "integrity": "sha512-86Ri699bwiHZVBzTzNj8gspqAhCPchg70zPVWIh3qzUOA1pUMcb272Em3LPk8AE0mS95B9yMJhtqF8vFJAn0dA==",
- "dependencies": {
- "limit-it": "^3.0.0",
- "typpy": "^2.1.0"
- }
- },
"node_modules/exec-sh": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz",
@@ -9940,14 +9891,6 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
- "node_modules/function.name": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.13.tgz",
- "integrity": "sha512-mVrqdoy5npWZyoXl4DxCeuVF6delDcQjVS9aPdvLYlBxtMTZDR2B5GVEQEoM1jJyspCqg3C0v4ABkLE7tp9xFA==",
- "dependencies": {
- "noop6": "^1.0.1"
- }
- },
"node_modules/functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
@@ -10017,47 +9960,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/git-package-json": {
- "version": "1.4.10",
- "resolved": "https://registry.npmjs.org/git-package-json/-/git-package-json-1.4.10.tgz",
- "integrity": "sha512-DRAcvbzd2SxGK7w8OgYfvKqhFliT5keX0lmSmVdgScgf1kkl5tbbo7Pam6uYoCa1liOiipKxQZG8quCtGWl/fA==",
- "dependencies": {
- "deffy": "^2.2.1",
- "err": "^1.1.1",
- "gry": "^5.0.0",
- "normalize-package-data": "^2.3.5",
- "oargv": "^3.4.1",
- "one-by-one": "^3.1.0",
- "r-json": "^1.2.1",
- "r-package-json": "^1.0.0",
- "tmp": "0.0.28"
- }
- },
- "node_modules/git-source": {
- "version": "1.1.10",
- "resolved": "https://registry.npmjs.org/git-source/-/git-source-1.1.10.tgz",
- "integrity": "sha512-XZZ7ZgnLL35oLgM/xjnLYgtlKlxJG0FohC1kWDvGkU7s1VKGXK0pFF/g1itQEwQ3D+uTQzBnzPi8XbqOv7Wc1Q==",
- "dependencies": {
- "git-url-parse": "^5.0.1"
- }
- },
- "node_modules/git-up": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz",
- "integrity": "sha1-JkSAoAax2EJhrB/gmjpRacV+oZ0=",
- "dependencies": {
- "is-ssh": "^1.0.0",
- "parse-url": "^1.0.0"
- }
- },
- "node_modules/git-url-parse": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz",
- "integrity": "sha1-/j15xnRq4FBIz6UIyB553du6OEM=",
- "dependencies": {
- "git-up": "^1.0.0"
- }
- },
"node_modules/glob": {
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
@@ -10150,51 +10052,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/got": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz",
- "integrity": "sha1-ux1+4WO3gIK7yOuDbz85UATqb78=",
- "dependencies": {
- "create-error-class": "^3.0.1",
- "duplexer2": "^0.1.4",
- "is-plain-obj": "^1.0.0",
- "is-redirect": "^1.0.0",
- "is-retry-allowed": "^1.0.0",
- "is-stream": "^1.0.0",
- "lowercase-keys": "^1.0.0",
- "node-status-codes": "^1.0.0",
- "object-assign": "^4.0.1",
- "parse-json": "^2.1.0",
- "pinkie-promise": "^2.0.0",
- "read-all-stream": "^3.0.0",
- "readable-stream": "^2.0.5",
- "timed-out": "^2.0.0",
- "unzip-response": "^1.0.0",
- "url-parse-lax": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/got/node_modules/is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/got/node_modules/parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
- "dependencies": {
- "error-ex": "^1.2.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
@@ -10206,17 +10063,6 @@
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"optional": true
},
- "node_modules/gry": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/gry/-/gry-5.0.8.tgz",
- "integrity": "sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==",
- "dependencies": {
- "abs": "^1.2.1",
- "exec-limiter": "^3.0.0",
- "one-by-one": "^3.0.0",
- "ul": "^5.0.0"
- }
- },
"node_modules/gzip-size": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
@@ -11434,14 +11280,6 @@
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
},
- "node_modules/is-redirect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
- "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -11470,14 +11308,6 @@
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg=="
},
- "node_modules/is-retry-allowed": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
- "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-root": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
@@ -11486,14 +11316,6 @@
"node": ">=6"
}
},
- "node_modules/is-ssh": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz",
- "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==",
- "dependencies": {
- "protocols": "^1.1.0"
- }
- },
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -11694,11 +11516,6 @@
"node": ">=8"
}
},
- "node_modules/iterate-object": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz",
- "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw=="
- },
"node_modules/jest": {
"version": "26.6.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz",
@@ -13413,14 +13230,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/limit-it": {
- "version": "3.2.10",
- "resolved": "https://registry.npmjs.org/limit-it/-/limit-it-3.2.10.tgz",
- "integrity": "sha512-T0NK99pHnkimldr1WUqvbGV1oWDku/xC9J/OqzJFsV1jeOS6Bwl8W7vkeQIBqwiON9dTALws+rX/XPMQqWerDQ==",
- "dependencies": {
- "typpy": "^2.0.0"
- }
- },
"node_modules/lines-and-columns": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@@ -13582,14 +13391,6 @@
"tslib": "^2.0.3"
}
},
- "node_modules/lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -14235,19 +14036,6 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
"integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
},
- "node_modules/node-status-codes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz",
- "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/noop6": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/noop6/-/noop6-1.0.9.tgz",
- "integrity": "sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA=="
- },
"node_modules/normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -14329,23 +14117,6 @@
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
"integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ=="
},
- "node_modules/oargv": {
- "version": "3.4.10",
- "resolved": "https://registry.npmjs.org/oargv/-/oargv-3.4.10.tgz",
- "integrity": "sha512-SXaMANv9sr7S/dP0vj0+Ybipa47UE1ntTWQ2rpPRhC6Bsvfl+Jg03Xif7jfL0sWKOYWK8oPjcZ5eJ82t8AP/8g==",
- "dependencies": {
- "iterate-object": "^1.1.0",
- "ul": "^5.0.0"
- }
- },
- "node_modules/obj-def": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/obj-def/-/obj-def-1.0.9.tgz",
- "integrity": "sha512-bQ4ya3VYD6FAA1+s6mEhaURRHSmw4+sKaXE6UyXZ1XDYc5D+c7look25dFdydmLd18epUegh398gdDkMUZI9xg==",
- "dependencies": {
- "deffy": "^2.2.2"
- }
- },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -14596,15 +14367,6 @@
"wrappy": "1"
}
},
- "node_modules/one-by-one": {
- "version": "3.2.8",
- "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.8.tgz",
- "integrity": "sha512-HR/pSzZdm46Xqj58K+Bu64kMbSTw8/u77AwWvV+rprO/OsuR++pPlkUJn+SmwqBGRgHKwSKQ974V3uls7crIeQ==",
- "dependencies": {
- "obj-def": "^1.0.0",
- "sliced": "^1.0.1"
- }
- },
"node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -14694,14 +14456,6 @@
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
},
- "node_modules/os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/p-each-series": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz",
@@ -14768,47 +14522,6 @@
"node": ">=6"
}
},
- "node_modules/package-json": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz",
- "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=",
- "dependencies": {
- "got": "^5.0.0",
- "registry-auth-token": "^3.0.1",
- "registry-url": "^3.0.3",
- "semver": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/package-json-path": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/package-json-path/-/package-json-path-1.0.9.tgz",
- "integrity": "sha512-uNu7f6Ef7tQHZRnkyVnCtzdSYVN9uBtge/sG7wzcUaawFWkPYUq67iXxRGrQSg/q0tzxIB8jSyIYUKjG2Jn//A==",
- "dependencies": {
- "abs": "^1.2.1"
- }
- },
- "node_modules/package-json/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/package.json": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz",
- "integrity": "sha1-+IYFnSpJ7QduZIg2ldc7K0bSHW0=",
- "deprecated": "Use pkg.json instead.",
- "dependencies": {
- "git-package-json": "^1.4.0",
- "git-source": "^1.1.0",
- "package-json": "^2.3.1"
- }
- },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -14873,15 +14586,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/parse-url": {
- "version": "1.3.11",
- "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz",
- "integrity": "sha1-V8FUKKuKiSsfQ4aWRccR0OFEtVQ=",
- "dependencies": {
- "is-ssh": "^1.3.0",
- "protocols": "^1.4.0"
- }
- },
"node_modules/parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@@ -16522,9 +16226,9 @@
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"node_modules/pretty-quick": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.1.tgz",
- "integrity": "sha512-ZYLGiMoV2jcaas3vTJrLvKAYsxDoXQBUn8OSTxkl67Fyov9lyXivJTl0+2WVh+y6EovGcw7Lm5ThYpH+Sh3XxQ==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz",
+ "integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==",
"dev": true,
"dependencies": {
"chalk": "^3.0.0",
@@ -16677,11 +16381,6 @@
"react": ">=0.14.0"
}
},
- "node_modules/protocols": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz",
- "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg=="
- },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -16828,20 +16527,6 @@
}
]
},
- "node_modules/r-json": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.2.10.tgz",
- "integrity": "sha512-hu9vyLjSlHXT62NAS7DjI9WazDlvjN0lgp3n431dCVnirVcLkZIpzSwA3orhZEKzdDD2jqNYI+w0yG0aFf4kpA=="
- },
- "node_modules/r-package-json": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/r-package-json/-/r-package-json-1.0.9.tgz",
- "integrity": "sha512-G4Vpf1KImWmmPFGdtWQTU0L9zk0SjqEC4qs/jE7AQ+Ylmr5kizMzGeC4wnHp5+ijPqNN+2ZPpvyjVNdN1CDVcg==",
- "dependencies": {
- "package-json-path": "^1.0.0",
- "r-json": "^1.2.1"
- }
- },
"node_modules/raf": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
@@ -16897,20 +16582,6 @@
"node": ">= 0.8"
}
},
- "node_modules/rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "dependencies": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "bin": {
- "rc": "cli.js"
- }
- },
"node_modules/rc-align": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.9.tgz",
@@ -17006,14 +16677,6 @@
"react-dom": ">=16.9.0"
}
},
- "node_modules/rc/node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/react": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
@@ -17717,18 +17380,6 @@
"react-dom": ">=16.6.0"
}
},
- "node_modules/read-all-stream": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
- "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=",
- "dependencies": {
- "pinkie-promise": "^2.0.0",
- "readable-stream": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -18035,26 +17686,6 @@
"node": ">=4"
}
},
- "node_modules/registry-auth-token": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
- "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
- "dependencies": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "dependencies": {
- "rc": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/regjsgen": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
@@ -19079,11 +18710,6 @@
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
- "node_modules/sliced": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
- "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
- },
"node_modules/snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -19244,17 +18870,16 @@
}
},
"node_modules/socket.io-client": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.1.3.tgz",
- "integrity": "sha512-hISFn6PDpgDifVUiNklLHVPTMv1LAk8poHArfIUdXa+gKgbr0MZbAlquDFqCqsF30yBqa+jg42wgos2FK50BHA==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.0.tgz",
+ "integrity": "sha512-g7riSEJXi7qCFImPow98oT8X++MSsHz6MMFRXkWNJ6uEROSHOa3kxdrsYWMq85dO+09CFMkcqlpjvbVXQl4z6g==",
"dependencies": {
- "@types/component-emitter": "^1.2.10",
+ "@socket.io/component-emitter": "~3.0.0",
"backo2": "~1.0.2",
- "component-emitter": "~1.3.0",
- "debug": "~4.3.1",
- "engine.io-client": "~5.1.2",
+ "debug": "~4.3.2",
+ "engine.io-client": "~6.1.1",
"parseuri": "0.0.6",
- "socket.io-parser": "~4.0.4"
+ "socket.io-parser": "~4.1.1"
},
"engines": {
"node": ">=10.0.0"
@@ -19282,12 +18907,11 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/socket.io-parser": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
- "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.1.tgz",
+ "integrity": "sha512-USQVLSkDWE5nbcY760ExdKaJxCE65kcsG/8k5FDGZVVxpD1pA7hABYXYkCUvxUuYYh/+uQw0N/fvBzfT8o07KA==",
"dependencies": {
- "@types/component-emitter": "^1.2.10",
- "component-emitter": "~1.3.0",
+ "@socket.io/component-emitter": "~3.0.0",
"debug": "~4.3.1"
},
"engines": {
@@ -20496,14 +20120,6 @@
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
},
- "node_modules/timed-out": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz",
- "integrity": "sha1-84sK6B03R9YoAB9B2vxlKs5nHAo=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -20530,17 +20146,6 @@
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
- "node_modules/tmp": {
- "version": "0.0.28",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz",
- "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=",
- "dependencies": {
- "os-tmpdir": "~1.0.1"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
@@ -20784,23 +20389,6 @@
"node": ">=4.2.0"
}
},
- "node_modules/typpy": {
- "version": "2.3.13",
- "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.3.13.tgz",
- "integrity": "sha512-vOxIcQz9sxHi+rT09SJ5aDgVgrPppQjwnnayTrMye1ODaU8gIZTDM19t9TxmEElbMihx2Nq/0/b/MtyKfayRqA==",
- "dependencies": {
- "function.name": "^1.0.3"
- }
- },
- "node_modules/ul": {
- "version": "5.2.15",
- "resolved": "https://registry.npmjs.org/ul/-/ul-5.2.15.tgz",
- "integrity": "sha512-svLEUy8xSCip5IWnsRa0UOg+2zP0Wsj4qlbjTmX6GJSmvKMHADBuHOm1dpNkWqWPIGuVSqzUkV3Cris5JrlTRQ==",
- "dependencies": {
- "deffy": "^2.2.2",
- "typpy": "^2.3.4"
- }
- },
"node_modules/unbox-primitive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
@@ -20994,14 +20582,6 @@
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
- "node_modules/unzip-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
- "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=",
- "engines": {
- "node": ">=0.10"
- }
- },
"node_modules/upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
@@ -21086,17 +20666,6 @@
"requires-port": "^1.0.0"
}
},
- "node_modules/url-parse-lax": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
- "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
- "dependencies": {
- "prepend-http": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/url/node_modules/punycode": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
@@ -22680,6 +22249,14 @@
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
+ "node_modules/xmlhttprequest-ssl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
+ "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -24990,6 +24567,11 @@
"@sinonjs/commons": "^1.7.0"
}
},
+ "@socket.io/component-emitter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz",
+ "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q=="
+ },
"@surma/rollup-plugin-off-main-thread": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz",
@@ -25160,11 +24742,6 @@
"@types/jquery": "*"
}
},
- "@types/component-emitter": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
- "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
- },
"@types/d3-path": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz",
@@ -25353,9 +24930,9 @@
}
},
"@types/react-dom": {
- "version": "17.0.9",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz",
- "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==",
+ "version": "17.0.11",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.11.tgz",
+ "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==",
"dev": true,
"requires": {
"@types/react": "*"
@@ -25845,14 +25422,6 @@
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
"integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q=="
},
- "abs": {
- "version": "1.3.14",
- "resolved": "https://registry.npmjs.org/abs/-/abs-1.3.14.tgz",
- "integrity": "sha512-PrS26IzwKLWwuURpiKl8wRmJ2KdR/azaVrLEBWG/TALwT20Y7qjtYp1qcMLHA4206hBHY5phv3w4pjf9NPv4Vw==",
- "requires": {
- "ul": "^5.0.0"
- }
- },
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -26735,9 +26304,9 @@
}
},
"base64-arraybuffer": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
- "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz",
+ "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA=="
},
"base64-js": {
"version": "1.5.1",
@@ -27161,11 +26730,6 @@
"rsvp": "^4.8.4"
}
},
- "capture-stack-trace": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
- "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw=="
- },
"case-sensitive-paths-webpack-plugin": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz",
@@ -27715,14 +27279,6 @@
}
}
},
- "create-error-class": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
- "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
- "requires": {
- "capture-stack-trace": "^1.0.0"
- }
- },
"create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
@@ -28230,11 +27786,6 @@
"regexp.prototype.flags": "^1.2.0"
}
},
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
- },
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -28334,14 +27885,6 @@
}
}
},
- "deffy": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.4.tgz",
- "integrity": "sha512-pLc9lsbsWjr6RxmJ2OLyvm+9l4j1yK69h+TML/gUit/t3vTijpkNGh8LioaJYTGO7F25m6HZndADcUOo2PsiUg==",
- "requires": {
- "typpy": "^2.0.0"
- }
- },
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -28637,14 +28180,6 @@
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
},
- "duplexer2": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
- "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
- "requires": {
- "readable-stream": "^2.0.2"
- }
- },
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -28721,18 +28256,18 @@
}
},
"engine.io-client": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-5.1.2.tgz",
- "integrity": "sha512-blRrgXIE0A/eurWXRzvfCLG7uUFJqfTGFsyJzXSK71srMMGJ2VraBLg8Mdw28uUxSpVicepBN9X7asqpD1mZcQ==",
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz",
+ "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==",
"requires": {
- "base64-arraybuffer": "0.1.4",
- "component-emitter": "~1.3.0",
+ "@socket.io/component-emitter": "~3.0.0",
"debug": "~4.3.1",
- "engine.io-parser": "~4.0.1",
+ "engine.io-parser": "~5.0.0",
"has-cors": "1.1.0",
"parseqs": "0.0.6",
"parseuri": "0.0.6",
- "ws": "~7.4.2",
+ "ws": "~8.2.3",
+ "xmlhttprequest-ssl": "~2.0.0",
"yeast": "0.1.2"
},
"dependencies": {
@@ -28748,15 +28283,21 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "ws": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
+ "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
+ "requires": {}
}
}
},
"engine.io-parser": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
- "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.2.tgz",
+ "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==",
"requires": {
- "base64-arraybuffer": "0.1.4"
+ "base64-arraybuffer": "~1.0.1"
}
},
"enhanced-resolve": {
@@ -28793,14 +28334,6 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
},
- "err": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/err/-/err-1.1.1.tgz",
- "integrity": "sha1-65KOLhGjFmSPeCgz0PlyWLpDwvg=",
- "requires": {
- "typpy": "^2.2.0"
- }
- },
"errno": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
@@ -29605,15 +29138,6 @@
"safe-buffer": "^5.1.1"
}
},
- "exec-limiter": {
- "version": "3.2.13",
- "resolved": "https://registry.npmjs.org/exec-limiter/-/exec-limiter-3.2.13.tgz",
- "integrity": "sha512-86Ri699bwiHZVBzTzNj8gspqAhCPchg70zPVWIh3qzUOA1pUMcb272Em3LPk8AE0mS95B9yMJhtqF8vFJAn0dA==",
- "requires": {
- "limit-it": "^3.0.0",
- "typpy": "^2.1.0"
- }
- },
"exec-sh": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz",
@@ -30282,14 +29806,6 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
- "function.name": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.13.tgz",
- "integrity": "sha512-mVrqdoy5npWZyoXl4DxCeuVF6delDcQjVS9aPdvLYlBxtMTZDR2B5GVEQEoM1jJyspCqg3C0v4ABkLE7tp9xFA==",
- "requires": {
- "noop6": "^1.0.1"
- }
- },
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
@@ -30338,47 +29854,6 @@
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
},
- "git-package-json": {
- "version": "1.4.10",
- "resolved": "https://registry.npmjs.org/git-package-json/-/git-package-json-1.4.10.tgz",
- "integrity": "sha512-DRAcvbzd2SxGK7w8OgYfvKqhFliT5keX0lmSmVdgScgf1kkl5tbbo7Pam6uYoCa1liOiipKxQZG8quCtGWl/fA==",
- "requires": {
- "deffy": "^2.2.1",
- "err": "^1.1.1",
- "gry": "^5.0.0",
- "normalize-package-data": "^2.3.5",
- "oargv": "^3.4.1",
- "one-by-one": "^3.1.0",
- "r-json": "^1.2.1",
- "r-package-json": "^1.0.0",
- "tmp": "0.0.28"
- }
- },
- "git-source": {
- "version": "1.1.10",
- "resolved": "https://registry.npmjs.org/git-source/-/git-source-1.1.10.tgz",
- "integrity": "sha512-XZZ7ZgnLL35oLgM/xjnLYgtlKlxJG0FohC1kWDvGkU7s1VKGXK0pFF/g1itQEwQ3D+uTQzBnzPi8XbqOv7Wc1Q==",
- "requires": {
- "git-url-parse": "^5.0.1"
- }
- },
- "git-up": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz",
- "integrity": "sha1-JkSAoAax2EJhrB/gmjpRacV+oZ0=",
- "requires": {
- "is-ssh": "^1.0.0",
- "parse-url": "^1.0.0"
- }
- },
- "git-url-parse": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz",
- "integrity": "sha1-/j15xnRq4FBIz6UIyB553du6OEM=",
- "requires": {
- "git-up": "^1.0.0"
- }
- },
"glob": {
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
@@ -30446,44 +29921,6 @@
"slash": "^3.0.0"
}
},
- "got": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz",
- "integrity": "sha1-ux1+4WO3gIK7yOuDbz85UATqb78=",
- "requires": {
- "create-error-class": "^3.0.1",
- "duplexer2": "^0.1.4",
- "is-plain-obj": "^1.0.0",
- "is-redirect": "^1.0.0",
- "is-retry-allowed": "^1.0.0",
- "is-stream": "^1.0.0",
- "lowercase-keys": "^1.0.0",
- "node-status-codes": "^1.0.0",
- "object-assign": "^4.0.1",
- "parse-json": "^2.1.0",
- "pinkie-promise": "^2.0.0",
- "read-all-stream": "^3.0.0",
- "readable-stream": "^2.0.5",
- "timed-out": "^2.0.0",
- "unzip-response": "^1.0.0",
- "url-parse-lax": "^1.0.0"
- },
- "dependencies": {
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
- },
- "parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
- "requires": {
- "error-ex": "^1.2.0"
- }
- }
- }
- },
"graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
@@ -30495,17 +29932,6 @@
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"optional": true
},
- "gry": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/gry/-/gry-5.0.8.tgz",
- "integrity": "sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==",
- "requires": {
- "abs": "^1.2.1",
- "exec-limiter": "^3.0.0",
- "one-by-one": "^3.0.0",
- "ul": "^5.0.0"
- }
- },
"gzip-size": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
@@ -31394,11 +30820,6 @@
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
},
- "is-redirect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
- "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
- },
"is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -31418,24 +30839,11 @@
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg=="
},
- "is-retry-allowed": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
- "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
- },
"is-root": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
"integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg=="
},
- "is-ssh": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz",
- "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==",
- "requires": {
- "protocols": "^1.1.0"
- }
- },
"is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -31577,11 +30985,6 @@
"istanbul-lib-report": "^3.0.0"
}
},
- "iterate-object": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz",
- "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw=="
- },
"jest": {
"version": "26.6.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz",
@@ -32879,14 +32282,6 @@
"type-check": "~0.4.0"
}
},
- "limit-it": {
- "version": "3.2.10",
- "resolved": "https://registry.npmjs.org/limit-it/-/limit-it-3.2.10.tgz",
- "integrity": "sha512-T0NK99pHnkimldr1WUqvbGV1oWDku/xC9J/OqzJFsV1jeOS6Bwl8W7vkeQIBqwiON9dTALws+rX/XPMQqWerDQ==",
- "requires": {
- "typpy": "^2.0.0"
- }
- },
"lines-and-columns": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@@ -33022,11 +32417,6 @@
"tslib": "^2.0.3"
}
},
- "lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
- },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -33554,16 +32944,6 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
"integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
},
- "node-status-codes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz",
- "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8="
- },
- "noop6": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/noop6/-/noop6-1.0.9.tgz",
- "integrity": "sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA=="
- },
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -33629,23 +33009,6 @@
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
"integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ=="
},
- "oargv": {
- "version": "3.4.10",
- "resolved": "https://registry.npmjs.org/oargv/-/oargv-3.4.10.tgz",
- "integrity": "sha512-SXaMANv9sr7S/dP0vj0+Ybipa47UE1ntTWQ2rpPRhC6Bsvfl+Jg03Xif7jfL0sWKOYWK8oPjcZ5eJ82t8AP/8g==",
- "requires": {
- "iterate-object": "^1.1.0",
- "ul": "^5.0.0"
- }
- },
- "obj-def": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/obj-def/-/obj-def-1.0.9.tgz",
- "integrity": "sha512-bQ4ya3VYD6FAA1+s6mEhaURRHSmw4+sKaXE6UyXZ1XDYc5D+c7look25dFdydmLd18epUegh398gdDkMUZI9xg==",
- "requires": {
- "deffy": "^2.2.2"
- }
- },
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -33825,15 +33188,6 @@
"wrappy": "1"
}
},
- "one-by-one": {
- "version": "3.2.8",
- "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.8.tgz",
- "integrity": "sha512-HR/pSzZdm46Xqj58K+Bu64kMbSTw8/u77AwWvV+rprO/OsuR++pPlkUJn+SmwqBGRgHKwSKQ974V3uls7crIeQ==",
- "requires": {
- "obj-def": "^1.0.0",
- "sliced": "^1.0.1"
- }
- },
"onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -33901,11 +33255,6 @@
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
},
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
- },
"p-each-series": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz",
@@ -33945,42 +33294,6 @@
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
- "package-json": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz",
- "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=",
- "requires": {
- "got": "^5.0.0",
- "registry-auth-token": "^3.0.1",
- "registry-url": "^3.0.3",
- "semver": "^5.1.0"
- },
- "dependencies": {
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- }
- }
- },
- "package-json-path": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/package-json-path/-/package-json-path-1.0.9.tgz",
- "integrity": "sha512-uNu7f6Ef7tQHZRnkyVnCtzdSYVN9uBtge/sG7wzcUaawFWkPYUq67iXxRGrQSg/q0tzxIB8jSyIYUKjG2Jn//A==",
- "requires": {
- "abs": "^1.2.1"
- }
- },
- "package.json": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz",
- "integrity": "sha1-+IYFnSpJ7QduZIg2ldc7K0bSHW0=",
- "requires": {
- "git-package-json": "^1.4.0",
- "git-source": "^1.1.0",
- "package-json": "^2.3.1"
- }
- },
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -34036,15 +33349,6 @@
"lines-and-columns": "^1.1.6"
}
},
- "parse-url": {
- "version": "1.3.11",
- "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz",
- "integrity": "sha1-V8FUKKuKiSsfQ4aWRccR0OFEtVQ=",
- "requires": {
- "is-ssh": "^1.3.0",
- "protocols": "^1.4.0"
- }
- },
"parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@@ -35367,9 +34671,9 @@
}
},
"pretty-quick": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.1.tgz",
- "integrity": "sha512-ZYLGiMoV2jcaas3vTJrLvKAYsxDoXQBUn8OSTxkl67Fyov9lyXivJTl0+2WVh+y6EovGcw7Lm5ThYpH+Sh3XxQ==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz",
+ "integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==",
"dev": true,
"requires": {
"chalk": "^3.0.0",
@@ -35485,11 +34789,6 @@
"warning": "^4.0.0"
}
},
- "protocols": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz",
- "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg=="
- },
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -35603,20 +34902,6 @@
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
},
- "r-json": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.2.10.tgz",
- "integrity": "sha512-hu9vyLjSlHXT62NAS7DjI9WazDlvjN0lgp3n431dCVnirVcLkZIpzSwA3orhZEKzdDD2jqNYI+w0yG0aFf4kpA=="
- },
- "r-package-json": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/r-package-json/-/r-package-json-1.0.9.tgz",
- "integrity": "sha512-G4Vpf1KImWmmPFGdtWQTU0L9zk0SjqEC4qs/jE7AQ+Ylmr5kizMzGeC4wnHp5+ijPqNN+2ZPpvyjVNdN1CDVcg==",
- "requires": {
- "package-json-path": "^1.0.0",
- "r-json": "^1.2.1"
- }
- },
"raf": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
@@ -35665,24 +34950,6 @@
}
}
},
- "rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "requires": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "dependencies": {
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
- }
- }
- },
"rc-align": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.9.tgz",
@@ -36288,15 +35555,6 @@
"prop-types": "^15.6.2"
}
},
- "read-all-stream": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
- "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=",
- "requires": {
- "pinkie-promise": "^2.0.0",
- "readable-stream": "^2.0.0"
- }
- },
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -36552,23 +35810,6 @@
"unicode-match-property-value-ecmascript": "^1.2.0"
}
},
- "registry-auth-token": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
- "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
- "requires": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
- }
- },
- "registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "requires": {
- "rc": "^1.0.1"
- }
- },
"regjsgen": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
@@ -37366,11 +36607,6 @@
"is-fullwidth-code-point": "^3.0.0"
}
},
- "sliced": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
- "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
- },
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -37499,17 +36735,16 @@
}
},
"socket.io-client": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.1.3.tgz",
- "integrity": "sha512-hISFn6PDpgDifVUiNklLHVPTMv1LAk8poHArfIUdXa+gKgbr0MZbAlquDFqCqsF30yBqa+jg42wgos2FK50BHA==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.0.tgz",
+ "integrity": "sha512-g7riSEJXi7qCFImPow98oT8X++MSsHz6MMFRXkWNJ6uEROSHOa3kxdrsYWMq85dO+09CFMkcqlpjvbVXQl4z6g==",
"requires": {
- "@types/component-emitter": "^1.2.10",
+ "@socket.io/component-emitter": "~3.0.0",
"backo2": "~1.0.2",
- "component-emitter": "~1.3.0",
- "debug": "~4.3.1",
- "engine.io-client": "~5.1.2",
+ "debug": "~4.3.2",
+ "engine.io-client": "~6.1.1",
"parseuri": "0.0.6",
- "socket.io-parser": "~4.0.4"
+ "socket.io-parser": "~4.1.1"
},
"dependencies": {
"debug": {
@@ -37528,12 +36763,11 @@
}
},
"socket.io-parser": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
- "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.1.tgz",
+ "integrity": "sha512-USQVLSkDWE5nbcY760ExdKaJxCE65kcsG/8k5FDGZVVxpD1pA7hABYXYkCUvxUuYYh/+uQw0N/fvBzfT8o07KA==",
"requires": {
- "@types/component-emitter": "^1.2.10",
- "component-emitter": "~1.3.0",
+ "@socket.io/component-emitter": "~3.0.0",
"debug": "~4.3.1"
},
"dependencies": {
@@ -38485,11 +37719,6 @@
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
},
- "timed-out": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz",
- "integrity": "sha1-84sK6B03R9YoAB9B2vxlKs5nHAo="
- },
"timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -38513,14 +37742,6 @@
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
- "tmp": {
- "version": "0.0.28",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz",
- "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=",
- "requires": {
- "os-tmpdir": "~1.0.1"
- }
- },
"tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
@@ -38706,23 +37927,6 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz",
"integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA=="
},
- "typpy": {
- "version": "2.3.13",
- "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.3.13.tgz",
- "integrity": "sha512-vOxIcQz9sxHi+rT09SJ5aDgVgrPppQjwnnayTrMye1ODaU8gIZTDM19t9TxmEElbMihx2Nq/0/b/MtyKfayRqA==",
- "requires": {
- "function.name": "^1.0.3"
- }
- },
- "ul": {
- "version": "5.2.15",
- "resolved": "https://registry.npmjs.org/ul/-/ul-5.2.15.tgz",
- "integrity": "sha512-svLEUy8xSCip5IWnsRa0UOg+2zP0Wsj4qlbjTmX6GJSmvKMHADBuHOm1dpNkWqWPIGuVSqzUkV3Cris5JrlTRQ==",
- "requires": {
- "deffy": "^2.2.2",
- "typpy": "^2.3.4"
- }
- },
"unbox-primitive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
@@ -38877,11 +38081,6 @@
}
}
},
- "unzip-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
- "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4="
- },
"upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
@@ -38952,14 +38151,6 @@
"requires-port": "^1.0.0"
}
},
- "url-parse-lax": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
- "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
- "requires": {
- "prepend-http": "^1.0.1"
- }
- },
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -40225,6 +39416,11 @@
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
+ "xmlhttprequest-ssl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
+ "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A=="
+ },
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 0ebd83d4a..4ec88d834 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -25,7 +25,6 @@
"bootstrap": "^4",
"lodash": "^4",
"moment": "^2.29.1",
- "package.json": "^2.0.1",
"rc-slider": "^9.7",
"react": "^17",
"react-bootstrap": "^1",
diff --git a/frontend/src/@types/api.d.ts b/frontend/src/@types/api.d.ts
index 043753879..2d820460a 100644
--- a/frontend/src/@types/api.d.ts
+++ b/frontend/src/@types/api.d.ts
@@ -33,6 +33,8 @@ declare namespace Language {
profileId: number;
cutoff: number | null;
items: ProfileItem[];
+ mustContain: string[];
+ mustNotContain: string[];
}
}
diff --git a/frontend/src/@types/settings.d.ts b/frontend/src/@types/settings.d.ts
index 8de53db86..16879f831 100644
--- a/frontend/src/@types/settings.d.ts
+++ b/frontend/src/@types/settings.d.ts
@@ -28,6 +28,8 @@ interface Settings {
declare namespace Settings {
interface General {
adaptive_searching: boolean;
+ adaptive_searching_delay: string;
+ adaptive_searching_delta: string;
anti_captcha_provider?: string;
auto_update: boolean;
base_url?: string;
diff --git a/frontend/src/App/Header.tsx b/frontend/src/App/Header.tsx
index 9ca33a574..0f91cadae 100644
--- a/frontend/src/App/Header.tsx
+++ b/frontend/src/App/Header.tsx
@@ -5,6 +5,7 @@ import {
faUser,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { uniqueId } from "lodash";
import React, { FunctionComponent, useMemo } from "react";
import {
Button,
@@ -35,16 +36,22 @@ async function SearchItem(text: string) {
return results.map((v) => {
let link: string;
+ let id: string;
if (v.sonarrSeriesId) {
link = `/series/${v.sonarrSeriesId}`;
+ id = `series-${v.sonarrSeriesId}`;
} else if (v.radarrId) {
link = `/movies/${v.radarrId}`;
+ id = `movie-${v.radarrId}`;
} else {
link = "";
+ id = uniqueId("unknown");
}
+
return {
name: `${v.title} (${v.year})`,
link,
+ id,
};
});
}
diff --git a/frontend/src/Settings/Languages/modal.tsx b/frontend/src/Settings/Languages/modal.tsx
index 20d1943a9..7371267dc 100644
--- a/frontend/src/Settings/Languages/modal.tsx
+++ b/frontend/src/Settings/Languages/modal.tsx
@@ -13,6 +13,7 @@ import {
ActionButton,
BaseModal,
BaseModalProps,
+ Chips,
LanguageSelector,
Selector,
SimpleTable,
@@ -31,6 +32,8 @@ function createDefaultProfile(): Language.Profile {
name: "",
items: [],
cutoff: null,
+ mustContain: [],
+ mustNotContain: [],
};
}
@@ -260,6 +263,28 @@ const LanguagesProfileModal: FunctionComponent = (
>
Ignore others if existing
+
+ updateProfile("mustContain", mc)}
+ >
+
+ Subtitles release info must include one of those words or they will be
+ excluded from search results (regex supported).
+
+
+
+ {
+ updateProfile("mustNotContain", mnc);
+ }}
+ >
+
+ Subtitles release info including one of those words (case insensitive)
+ will be excluded from search results (regex supported).
+
+
);
};
diff --git a/frontend/src/Settings/Languages/table.tsx b/frontend/src/Settings/Languages/table.tsx
index 4547e3198..10b71ca60 100644
--- a/frontend/src/Settings/Languages/table.tsx
+++ b/frontend/src/Settings/Languages/table.tsx
@@ -94,6 +94,40 @@ const Table: FunctionComponent = () => {
});
},
},
+ {
+ Header: "Must contain",
+ accessor: "mustContain",
+ Cell: (row) => {
+ const items = row.value;
+ if (!items) {
+ return false;
+ }
+ return items.map((v) => {
+ return (
+
+ {v}
+
+ );
+ });
+ },
+ },
+ {
+ Header: "Must not contain",
+ accessor: "mustNotContain",
+ Cell: (row) => {
+ const items = row.value;
+ if (!items) {
+ return false;
+ }
+ return items.map((v) => {
+ return (
+
+ {v}
+
+ );
+ });
+ },
+ },
{
accessor: "profileId",
Cell: ({ row, update }) => {
@@ -138,6 +172,8 @@ const Table: FunctionComponent = () => {
name: "",
items: [],
cutoff: null,
+ mustContain: [],
+ mustNotContain: [],
};
showModal("profile", profile);
}}
diff --git a/frontend/src/Settings/Providers/list.ts b/frontend/src/Settings/Providers/list.ts
index dc076eb1c..e1e24a96c 100644
--- a/frontend/src/Settings/Providers/list.ts
+++ b/frontend/src/Settings/Providers/list.ts
@@ -21,6 +21,10 @@ export const ProviderList: Readonly = [
defaultKey: {
username: "",
password: "",
+ vip: false,
+ },
+ keyNameOverride: {
+ vip: "VIP",
},
},
{ key: "argenteam", description: "LATAM Spanish Subtitles Provider" },
@@ -46,6 +50,21 @@ export const ProviderList: Readonly = [
key: "bsplayer",
name: "BSplayer",
},
+ {
+ key: "embeddedsubtitles",
+ name: "Embedded Subtitles",
+ description: "Embedded Subtitles from your Media Files",
+ defaultKey: {
+ include_srt: true,
+ include_ass: true,
+ },
+ message:
+ "Warning for cloud users: this provider needs to read the entire file in order to extract subtitles.",
+ keyNameOverride: {
+ include_srt: "Include SRT",
+ include_ass: "Include ASS (will be converted to SRT)",
+ },
+ },
{
key: "greeksubs",
name: "GreekSubs",
diff --git a/frontend/src/Settings/Sonarr/index.tsx b/frontend/src/Settings/Sonarr/index.tsx
index 6f9140d35..75ae9b3a1 100644
--- a/frontend/src/Settings/Sonarr/index.tsx
+++ b/frontend/src/Settings/Sonarr/index.tsx
@@ -97,6 +97,16 @@ const SettingsSonarrView: FunctionComponent = () => {
episodes in Sonarr.
+
+
+
+ Episodes from season zero (extras) from automatic download of
+ subtitles.
+
+
diff --git a/frontend/src/Settings/Subtitles/index.tsx b/frontend/src/Settings/Subtitles/index.tsx
index 4f5f05db9..20bdc72d7 100644
--- a/frontend/src/Settings/Subtitles/index.tsx
+++ b/frontend/src/Settings/Subtitles/index.tsx
@@ -10,7 +10,13 @@ import {
Slider,
Text,
} from "../components";
-import { antiCaptchaOption, colorOptions, folderOptions } from "./options";
+import {
+ adaptiveSearchingDelayOption,
+ adaptiveSearchingDeltaOption,
+ antiCaptchaOption,
+ colorOptions,
+ folderOptions,
+} from "./options";
const subzeroOverride = (key: string) => {
return (settings: Settings) => {
@@ -124,16 +130,44 @@ const SettingsSubtitlesView: FunctionComponent = () => {
-
-
-
- When searching for subtitles, Bazarr will search less frequently to
- limit call to providers.
-
-
+
+
+
+
+
+ When searching for subtitles, Bazarr will reduce search
+ frequency to limit call to providers.
+
+
+
+
+
+ (v === undefined ? "3w" : v)}
+ options={adaptiveSearchingDelayOption}
+ >
+
+ How much weeks must Bazarr wait after initial search to reduce
+ search frequency.
+
+
+
+ (v === undefined ? "1w" : v)}
+ options={adaptiveSearchingDeltaOption}
+ >
+
+ How often should Bazarr search for subtitles when in adaptive
+ search mode.
+
+
+
+
[] = [
},
];
+export const adaptiveSearchingDelayOption: SelectorOption[] = [
+ {
+ label: "1 week",
+ value: "1w",
+ },
+ {
+ label: "2 weeks",
+ value: "2w",
+ },
+ {
+ label: "3 weeks",
+ value: "3w",
+ },
+ {
+ label: "4 weeks",
+ value: "4w",
+ },
+];
+
+export const adaptiveSearchingDeltaOption: SelectorOption[] = [
+ {
+ label: "3 days",
+ value: "3d",
+ },
+ {
+ label: "1 week",
+ value: "1w",
+ },
+ {
+ label: "2 weeks",
+ value: "2w",
+ },
+ {
+ label: "3 weeks",
+ value: "3w",
+ },
+ {
+ label: "4 weeks",
+ value: "4w",
+ },
+];
+
function buildColor(name: string) {
return `color(name=${name})`;
}
diff --git a/frontend/src/Settings/components/forms.tsx b/frontend/src/Settings/components/forms.tsx
index 844fe26ab..6ffe92f30 100644
--- a/frontend/src/Settings/components/forms.tsx
+++ b/frontend/src/Settings/components/forms.tsx
@@ -176,11 +176,11 @@ export const Chips: FunctionComponent = (props) => {
const update = useSingleUpdate();
- const defaultValue = useLatest(settingKey, isArray, override);
+ const value = useLatest(settingKey, isArray, override);
return (
{
update(v, settingKey);
}}
diff --git a/frontend/src/components/SearchBar.tsx b/frontend/src/components/SearchBar.tsx
index 66c5db321..86ad517a8 100644
--- a/frontend/src/components/SearchBar.tsx
+++ b/frontend/src/components/SearchBar.tsx
@@ -10,6 +10,7 @@ import { useHistory } from "react-router";
import { useThrottle } from "rooks";
export interface SearchResult {
+ id: string;
name: string;
link?: string;
}
@@ -58,7 +59,7 @@ export const SearchBar: FunctionComponent = ({
const items = useMemo(() => {
const its = results.map((v) => (
diff --git a/frontend/src/components/inputs/Chips.tsx b/frontend/src/components/inputs/Chips.tsx
index ce136731a..1be0050a0 100644
--- a/frontend/src/components/inputs/Chips.tsx
+++ b/frontend/src/components/inputs/Chips.tsx
@@ -3,6 +3,7 @@ import React, {
FunctionComponent,
KeyboardEvent,
useCallback,
+ useEffect,
useMemo,
useRef,
useState,
@@ -14,15 +15,31 @@ const SplitKeys = ["Tab", "Enter", " ", ",", ";"];
export interface ChipsProps {
disabled?: boolean;
defaultValue?: readonly string[];
+ value?: readonly string[];
onChange?: (v: string[]) => void;
}
export const Chips: FunctionComponent = ({
defaultValue,
+ value,
disabled,
onChange,
}) => {
- const [chips, setChips] = useState(defaultValue ?? []);
+ const [chips, setChips] = useState>(() => {
+ if (value) {
+ return value;
+ }
+ if (defaultValue) {
+ return defaultValue;
+ }
+ return [];
+ });
+
+ useEffect(() => {
+ if (value) {
+ setChips(value);
+ }
+ }, [value]);
const input = useRef(null);
diff --git a/frontend/src/components/modals/toolOptions.ts b/frontend/src/components/modals/toolOptions.ts
index 27bfcbb07..5639cd4d0 100644
--- a/frontend/src/components/modals/toolOptions.ts
+++ b/frontend/src/components/modals/toolOptions.ts
@@ -13,8 +13,8 @@ export const availableTranslation = {
ca: "catalan",
ceb: "cebuano",
ny: "chichewa",
- "zh-cn": "chinese (simplified)",
- "zh-tw": "chinese (traditional)",
+ zh: "chinese (simplified)",
+ zt: "chinese (traditional)",
co: "corsican",
hr: "croatian",
cs: "czech",
diff --git a/libs/apprise/Apprise.py b/libs/apprise/Apprise.py
index b95da22a7..8930b2a77 100644
--- a/libs/apprise/Apprise.py
+++ b/libs/apprise/Apprise.py
@@ -34,6 +34,7 @@ from .common import MATCH_ALL_TAG
from .utils import is_exclusive_match
from .utils import parse_list
from .utils import parse_urls
+from .utils import cwe312_url
from .logger import logger
from .AppriseAsset import AppriseAsset
@@ -58,13 +59,15 @@ class Apprise(object):
"""
- def __init__(self, servers=None, asset=None, debug=False):
+ def __init__(self, servers=None, asset=None, location=None, debug=False):
"""
Loads a set of server urls while applying the Asset() module to each
if specified.
If no asset is provided, then the default asset is used.
+ Optionally specify a global ContentLocation for a more strict means
+ of handling Attachments.
"""
# Initialize a server list of URLs
@@ -87,6 +90,11 @@ class Apprise(object):
# Set our debug flag
self.debug = debug
+ # Store our hosting location for optional strict rule handling
+ # of Attachments. Setting this to None removes any attachment
+ # restrictions.
+ self.location = location
+
@staticmethod
def instantiate(url, asset=None, tag=None, suppress_exceptions=True):
"""
@@ -116,9 +124,14 @@ class Apprise(object):
# Initialize our result set
results = None
+ # Prepare our Asset Object
+ asset = asset if isinstance(asset, AppriseAsset) else AppriseAsset()
+
if isinstance(url, six.string_types):
# Acquire our url tokens
- results = plugins.url_to_dict(url)
+ results = plugins.url_to_dict(
+ url, secure_logging=asset.secure_logging)
+
if results is None:
# Failed to parse the server URL; detailed logging handled
# inside url_to_dict - nothing to report here.
@@ -132,25 +145,40 @@ class Apprise(object):
# schema is a mandatory dictionary item as it is the only way
# we can index into our loaded plugins
logger.error('Dictionary does not include a "schema" entry.')
- logger.trace('Invalid dictionary unpacked as:{}{}'.format(
- os.linesep, os.linesep.join(
- ['{}="{}"'.format(k, v) for k, v in results.items()])))
+ logger.trace(
+ 'Invalid dictionary unpacked as:{}{}'.format(
+ os.linesep, os.linesep.join(
+ ['{}="{}"'.format(k, v)
+ for k, v in results.items()])))
return None
- logger.trace('Dictionary unpacked as:{}{}'.format(
- os.linesep, os.linesep.join(
- ['{}="{}"'.format(k, v) for k, v in results.items()])))
+ logger.trace(
+ 'Dictionary unpacked as:{}{}'.format(
+ os.linesep, os.linesep.join(
+ ['{}="{}"'.format(k, v) for k, v in results.items()])))
+ # Otherwise we handle the invalid input specified
else:
- logger.error('Invalid URL specified: {}'.format(url))
+ logger.error(
+ 'An invalid URL type (%s) was specified for instantiation',
+ type(url))
+ return None
+
+ if not plugins.SCHEMA_MAP[results['schema']].enabled:
+ #
+ # First Plugin Enable Check (Pre Initialization)
+ #
+
+ # Plugin has been disabled at a global level
+ logger.error(
+ '%s:// is disabled on this system.', results['schema'])
return None
# Build a list of tags to associate with the newly added notifications
results['tag'] = set(parse_list(tag))
- # Prepare our Asset Object
- results['asset'] = \
- asset if isinstance(asset, AppriseAsset) else AppriseAsset()
+ # Set our Asset Object
+ results['asset'] = asset
if suppress_exceptions:
try:
@@ -159,14 +187,21 @@ class Apprise(object):
plugin = plugins.SCHEMA_MAP[results['schema']](**results)
# Create log entry of loaded URL
- logger.debug('Loaded {} URL: {}'.format(
- plugins.SCHEMA_MAP[results['schema']].service_name,
- plugin.url()))
+ logger.debug(
+ 'Loaded {} URL: {}'.format(
+ plugins.SCHEMA_MAP[results['schema']].service_name,
+ plugin.url(privacy=asset.secure_logging)))
except Exception:
+ # CWE-312 (Secure Logging) Handling
+ loggable_url = url if not asset.secure_logging \
+ else cwe312_url(url)
+
# the arguments are invalid or can not be used.
- logger.error('Could not load {} URL: {}'.format(
- plugins.SCHEMA_MAP[results['schema']].service_name, url))
+ logger.error(
+ 'Could not load {} URL: {}'.format(
+ plugins.SCHEMA_MAP[results['schema']].service_name,
+ loggable_url))
return None
else:
@@ -174,6 +209,24 @@ class Apprise(object):
# URL information but don't wrap it in a try catch
plugin = plugins.SCHEMA_MAP[results['schema']](**results)
+ if not plugin.enabled:
+ #
+ # Second Plugin Enable Check (Post Initialization)
+ #
+
+ # Service/Plugin is disabled (on a more local level). This is a
+ # case where the plugin was initially enabled but then after the
+ # __init__() was called under the hood something pre-determined
+ # that it could no longer be used.
+
+ # The only downside to doing it this way is services are
+ # initialized prior to returning the details() if 3rd party tools
+ # are polling what is available. These services that become
+ # disabled thereafter are shown initially that they can be used.
+ logger.error(
+ '%s:// has become disabled on this system.', results['schema'])
+ return None
+
return plugin
def add(self, servers, asset=None, tag=None):
@@ -286,7 +339,8 @@ class Apprise(object):
return
def notify(self, body, title='', notify_type=NotifyType.INFO,
- body_format=None, tag=MATCH_ALL_TAG, attach=None):
+ body_format=None, tag=MATCH_ALL_TAG, attach=None,
+ interpret_escapes=None):
"""
Send a notification to all of the plugins previously loaded.
@@ -306,47 +360,158 @@ class Apprise(object):
Attach can contain a list of attachment URLs. attach can also be
represented by a an AttachBase() (or list of) object(s). This
identifies the products you wish to notify
+
+ Set interpret_escapes to True if you want to pre-escape a string
+ such as turning a \n into an actual new line, etc.
+ """
+
+ if ASYNCIO_SUPPORT:
+ return py3compat.asyncio.tosync(
+ self.async_notify(
+ body, title,
+ notify_type=notify_type, body_format=body_format,
+ tag=tag, attach=attach,
+ interpret_escapes=interpret_escapes,
+ ),
+ debug=self.debug
+ )
+
+ else:
+ try:
+ results = list(
+ self._notifyall(
+ Apprise._notifyhandler,
+ body, title,
+ notify_type=notify_type, body_format=body_format,
+ tag=tag, attach=attach,
+ interpret_escapes=interpret_escapes,
+ )
+ )
+
+ except TypeError:
+ # No notifications sent, and there was an internal error.
+ return False
+
+ else:
+ if len(results) > 0:
+ # All notifications sent, return False if any failed.
+ return all(results)
+
+ else:
+ # No notifications sent.
+ return None
+
+ def async_notify(self, *args, **kwargs):
+ """
+ Send a notification to all of the plugins previously loaded, for
+ asynchronous callers. This method is an async method that should be
+ awaited on, even if it is missing the async keyword in its signature.
+ (This is omitted to preserve syntax compatibility with Python 2.)
+
+ The arguments are identical to those of Apprise.notify(). This method
+ is not available in Python 2.
+ """
+
+ try:
+ coroutines = list(
+ self._notifyall(
+ Apprise._notifyhandlerasync, *args, **kwargs))
+
+ except TypeError:
+ # No notifications sent, and there was an internal error.
+ return py3compat.asyncio.toasyncwrap(False)
+
+ else:
+ if len(coroutines) > 0:
+ # All notifications sent, return False if any failed.
+ return py3compat.asyncio.notify(coroutines)
+
+ else:
+ # No notifications sent.
+ return py3compat.asyncio.toasyncwrap(None)
+
+ @staticmethod
+ def _notifyhandler(server, **kwargs):
+ """
+ The synchronous notification sender. Returns True if the notification
+ sent successfully.
+ """
+
+ try:
+ # Send notification
+ return server.notify(**kwargs)
+
+ except TypeError:
+ # These our our internally thrown notifications
+ return False
+
+ except Exception:
+ # A catch all so we don't have to abort early
+ # just because one of our plugins has a bug in it.
+ logger.exception("Unhandled Notification Exception")
+ return False
+
+ @staticmethod
+ def _notifyhandlerasync(server, **kwargs):
+ """
+ The asynchronous notification sender. Returns a coroutine that yields
+ True if the notification sent successfully.
+ """
+
+ if server.asset.async_mode:
+ return server.async_notify(**kwargs)
+
+ else:
+ # Send the notification immediately, and wrap the result in a
+ # coroutine.
+ status = Apprise._notifyhandler(server, **kwargs)
+ return py3compat.asyncio.toasyncwrap(status)
+
+ def _notifyall(self, handler, body, title='', notify_type=NotifyType.INFO,
+ body_format=None, tag=MATCH_ALL_TAG, attach=None,
+ interpret_escapes=None):
+ """
+ Creates notifications for all of the plugins loaded.
+
+ Returns a generator that calls handler for each notification. The first
+ and only argument supplied to handler is the server, and the keyword
+ arguments are exactly as they would be passed to server.notify().
"""
if len(self) == 0:
# Nothing to notify
- return False
-
- # Initialize our return result which only turns to True if we send
- # at least one valid notification
- status = None
+ raise TypeError("No service(s) to notify")
if not (title or body):
- return False
+ raise TypeError("No message content specified to deliver")
+
+ if six.PY2:
+ # Python 2.7.x Unicode Character Handling
+ # Ensure we're working with utf-8
+ if isinstance(title, unicode): # noqa: F821
+ title = title.encode('utf-8')
+
+ if isinstance(body, unicode): # noqa: F821
+ body = body.encode('utf-8')
# Tracks conversions
conversion_map = dict()
# Prepare attachments if required
if attach is not None and not isinstance(attach, AppriseAttachment):
- try:
- attach = AppriseAttachment(attach, asset=self.asset)
-
- except TypeError:
- # bad attachments
- return False
+ attach = AppriseAttachment(
+ attach, asset=self.asset, location=self.location)
# Allow Asset default value
body_format = self.asset.body_format \
if body_format is None else body_format
- # for asyncio support; we track a list of our servers to notify
- # sequentially
- coroutines = []
+ # Allow Asset default value
+ interpret_escapes = self.asset.interpret_escapes \
+ if interpret_escapes is None else interpret_escapes
# Iterate over our loaded plugins
for server in self.find(tag):
- if status is None:
- # We have at least one server to notify; change status
- # to be a default value of True from now (purely an
- # initialiation at this point)
- status = True
-
# If our code reaches here, we either did not define a tag (it
# was set to None), or we did define a tag and the logic above
# determined we need to notify the service it's associated with
@@ -396,48 +561,59 @@ class Apprise(object):
# Store entry directly
conversion_map[server.notify_format] = body
- if ASYNCIO_SUPPORT and server.asset.async_mode:
- # Build a list of servers requiring notification
- # that will be triggered asynchronously afterwards
- coroutines.append(server.async_notify(
- body=conversion_map[server.notify_format],
- title=title,
- notify_type=notify_type,
- attach=attach))
+ if interpret_escapes:
+ #
+ # Escape our content
+ #
- # We gather at this point and notify at the end
- continue
+ try:
+ # Added overhead required due to Python 3 Encoding Bug
+ # identified here: https://bugs.python.org/issue21331
+ conversion_map[server.notify_format] = \
+ conversion_map[server.notify_format]\
+ .encode('ascii', 'backslashreplace')\
+ .decode('unicode-escape')
- try:
- # Send notification
- if not server.notify(
- body=conversion_map[server.notify_format],
- title=title,
- notify_type=notify_type,
- attach=attach):
+ except UnicodeDecodeError: # pragma: no cover
+ # This occurs using a very old verion of Python 2.7 such
+ # as the one that ships with CentOS/RedHat 7.x (v2.7.5).
+ conversion_map[server.notify_format] = \
+ conversion_map[server.notify_format] \
+ .decode('string_escape')
- # Toggle our return status flag
- status = False
+ except AttributeError:
+ # Must be of string type
+ logger.error('Failed to escape message body')
+ raise TypeError
- except TypeError:
- # These our our internally thrown notifications
- status = False
+ if title:
+ try:
+ # Added overhead required due to Python 3 Encoding Bug
+ # identified here: https://bugs.python.org/issue21331
+ title = title\
+ .encode('ascii', 'backslashreplace')\
+ .decode('unicode-escape')
- except Exception:
- # A catch all so we don't have to abort early
- # just because one of our plugins has a bug in it.
- logger.exception("Notification Exception")
- status = False
+ except UnicodeDecodeError: # pragma: no cover
+ # This occurs using a very old verion of Python 2.7
+ # such as the one that ships with CentOS/RedHat 7.x
+ # (v2.7.5).
+ title = title.decode('string_escape')
- if coroutines:
- # perform our async notification(s)
- if not py3compat.asyncio.notify(coroutines, debug=self.debug):
- # Toggle our status only if we had a failure
- status = False
+ except AttributeError:
+ # Must be of string type
+ logger.error('Failed to escape message title')
+ raise TypeError
- return status
+ yield handler(
+ server,
+ body=conversion_map[server.notify_format],
+ title=title,
+ notify_type=notify_type,
+ attach=attach
+ )
- def details(self, lang=None):
+ def details(self, lang=None, show_requirements=False, show_disabled=False):
"""
Returns the details associated with the Apprise object
@@ -453,8 +629,27 @@ class Apprise(object):
'asset': self.asset.details(),
}
- # to add it's mapping to our hash table
for plugin in set(plugins.SCHEMA_MAP.values()):
+ # Iterate over our hashed plugins and dynamically build details on
+ # their status:
+
+ content = {
+ 'service_name': getattr(plugin, 'service_name', None),
+ 'service_url': getattr(plugin, 'service_url', None),
+ 'setup_url': getattr(plugin, 'setup_url', None),
+ # Placeholder - populated below
+ 'details': None
+ }
+
+ # Standard protocol(s) should be None or a tuple
+ enabled = getattr(plugin, 'enabled', True)
+ if not show_disabled and not enabled:
+ # Do not show inactive plugins
+ continue
+
+ elif show_disabled:
+ # Add current state to response
+ content['enabled'] = enabled
# Standard protocol(s) should be None or a tuple
protocols = getattr(plugin, 'protocol', None)
@@ -466,31 +661,35 @@ class Apprise(object):
if isinstance(secure_protocols, six.string_types):
secure_protocols = (secure_protocols, )
+ # Add our protocol details to our content
+ content.update({
+ 'protocols': protocols,
+ 'secure_protocols': secure_protocols,
+ })
+
if not lang:
# Simply return our results
- details = plugins.details(plugin)
+ content['details'] = plugins.details(plugin)
+ if show_requirements:
+ content['requirements'] = plugins.requirements(plugin)
+
else:
# Emulate the specified language when returning our results
with self.locale.lang_at(lang):
- details = plugins.details(plugin)
+ content['details'] = plugins.details(plugin)
+ if show_requirements:
+ content['requirements'] = plugins.requirements(plugin)
# Build our response object
- response['schemas'].append({
- 'service_name': getattr(plugin, 'service_name', None),
- 'service_url': getattr(plugin, 'service_url', None),
- 'setup_url': getattr(plugin, 'setup_url', None),
- 'protocols': protocols,
- 'secure_protocols': secure_protocols,
- 'details': details,
- })
+ response['schemas'].append(content)
return response
- def urls(self):
+ def urls(self, privacy=False):
"""
Returns all of the loaded URLs defined in this apprise object.
"""
- return [x.url() for x in self.servers]
+ return [x.url(privacy=privacy) for x in self.servers]
def pop(self, index):
"""
@@ -592,3 +791,7 @@ class Apprise(object):
"""
return sum([1 if not isinstance(s, (ConfigBase, AppriseConfig))
else len(s.servers()) for s in self.servers])
+
+
+if six.PY2:
+ del Apprise.async_notify
diff --git a/libs/apprise/Apprise.pyi b/libs/apprise/Apprise.pyi
new file mode 100644
index 000000000..919d370db
--- /dev/null
+++ b/libs/apprise/Apprise.pyi
@@ -0,0 +1,63 @@
+from typing import Any, Dict, List, Iterable, Iterator, Optional
+
+from . import (AppriseAsset, AppriseAttachment, AppriseConfig, ConfigBase,
+ NotifyBase, NotifyFormat, NotifyType)
+from .common import ContentLocation
+
+_Server = Union[str, ConfigBase, NotifyBase, AppriseConfig]
+_Servers = Union[_Server, Dict[Any, _Server], Iterable[_Server]]
+# Can't define this recursively as mypy doesn't support recursive types:
+# https://github.com/python/mypy/issues/731
+_Tag = Union[str, Iterable[Union[str, Iterable[str]]]]
+
+class Apprise:
+ def __init__(
+ self,
+ servers: _Servers = ...,
+ asset: Optional[AppriseAsset] = ...,
+ location: Optional[ContentLocation] = ...,
+ debug: bool = ...
+ ) -> None: ...
+ @staticmethod
+ def instantiate(
+ url: Union[str, Dict[str, NotifyBase]],
+ asset: Optional[AppriseAsset] = ...,
+ tag: Optional[_Tag] = ...,
+ suppress_exceptions: bool = ...
+ ) -> NotifyBase: ...
+ def add(
+ self,
+ servers: _Servers = ...,
+ asset: Optional[AppriseAsset] = ...,
+ tag: Optional[_Tag] = ...
+ ) -> bool: ...
+ def clear(self) -> None: ...
+ def find(self, tag: str = ...) -> Iterator[Apprise]: ...
+ def notify(
+ self,
+ body: str,
+ title: str = ...,
+ notify_type: NotifyType = ...,
+ body_format: NotifyFormat = ...,
+ tag: _Tag = ...,
+ attach: Optional[AppriseAttachment] = ...,
+ interpret_escapes: Optional[bool] = ...
+ ) -> bool: ...
+ async def async_notify(
+ self,
+ body: str,
+ title: str = ...,
+ notify_type: NotifyType = ...,
+ body_format: NotifyFormat = ...,
+ tag: _Tag = ...,
+ attach: Optional[AppriseAttachment] = ...,
+ interpret_escapes: Optional[bool] = ...
+ ) -> bool: ...
+ def details(self, lang: Optional[str] = ...) -> Dict[str, Any]: ...
+ def urls(self, privacy: bool = ...) -> Iterable[str]: ...
+ def pop(self, index: int) -> ConfigBase: ...
+ def __getitem__(self, index: int) -> ConfigBase: ...
+ def __bool__(self) -> bool: ...
+ def __nonzero__(self) -> bool: ...
+ def __iter__(self) -> Iterator[ConfigBase]: ...
+ def __len__(self) -> int: ...
\ No newline at end of file
diff --git a/libs/apprise/AppriseAsset.py b/libs/apprise/AppriseAsset.py
index 123da7225..e2e95b4a7 100644
--- a/libs/apprise/AppriseAsset.py
+++ b/libs/apprise/AppriseAsset.py
@@ -24,7 +24,7 @@
# THE SOFTWARE.
import re
-
+from uuid import uuid4
from os.path import join
from os.path import dirname
from os.path import isfile
@@ -105,6 +105,36 @@ class AppriseAsset(object):
# notifications are sent sequentially (one after another)
async_mode = True
+ # Whether or not to interpret escapes found within the input text prior
+ # to passing it upstream. Such as converting \t to an actual tab and \n
+ # to a new line.
+ interpret_escapes = False
+
+ # For more detail see CWE-312 @
+ # https://cwe.mitre.org/data/definitions/312.html
+ #
+ # By enabling this, the logging output has additional overhead applied to
+ # it preventing secure password and secret information from being
+ # displayed in the logging. Since there is overhead involved in performing
+ # this cleanup; system owners who run in a very isolated environment may
+ # choose to disable this for a slight performance bump. It is recommended
+ # that you leave this option as is otherwise.
+ secure_logging = True
+
+ # All internal/system flags are prefixed with an underscore (_)
+ # These can only be initialized using Python libraries and are not picked
+ # up from (yaml) configuration files (if set)
+
+ # An internal counter that is used by AppriseAPI
+ # (https://github.com/caronc/apprise-api). The idea is to allow one
+ # instance of AppriseAPI to call another, but to track how many times
+ # this occurs. It's intent is to prevent a loop where an AppriseAPI
+ # Server calls itself (or loops indefinitely)
+ _recursion = 0
+
+ # A unique identifer we can use to associate our calling source
+ _uid = str(uuid4())
+
def __init__(self, **kwargs):
"""
Asset Initialization
diff --git a/libs/apprise/AppriseAsset.pyi b/libs/apprise/AppriseAsset.pyi
new file mode 100644
index 000000000..08303341b
--- /dev/null
+++ b/libs/apprise/AppriseAsset.pyi
@@ -0,0 +1,34 @@
+from typing import Dict, Optional
+
+from . import NotifyFormat, NotifyType
+
+class AppriseAsset:
+ app_id: str
+ app_desc: str
+ app_url: str
+ html_notify_map: Dict[NotifyType, str]
+ default_html_color: str
+ default_extension: str
+ theme: Optional[str]
+ image_url_mask: str
+ image_url_logo: str
+ image_path_mask: Optional[str]
+ body_format: Optional[NotifyFormat]
+ async_mode: bool
+ interpret_escapes: bool
+ def __init__(
+ self,
+ app_id: str = ...,
+ app_desc: str = ...,
+ app_url: str = ...,
+ html_notify_map: Dict[NotifyType, str] = ...,
+ default_html_color: str = ...,
+ default_extension: str = ...,
+ theme: Optional[str] = ...,
+ image_url_mask: str = ...,
+ image_url_logo: str = ...,
+ image_path_mask: Optional[str] = ...,
+ body_format: Optional[NotifyFormat] = ...,
+ async_mode: bool = ...,
+ interpret_escapes: bool = ...
+ ) -> None: ...
\ No newline at end of file
diff --git a/libs/apprise/AppriseAttachment.py b/libs/apprise/AppriseAttachment.py
index a8f27e179..37d2c0901 100644
--- a/libs/apprise/AppriseAttachment.py
+++ b/libs/apprise/AppriseAttachment.py
@@ -29,6 +29,8 @@ from . import attachment
from . import URLBase
from .AppriseAsset import AppriseAsset
from .logger import logger
+from .common import ContentLocation
+from .common import CONTENT_LOCATIONS
from .utils import GET_SCHEMA_RE
@@ -38,7 +40,8 @@ class AppriseAttachment(object):
"""
- def __init__(self, paths=None, asset=None, cache=True, **kwargs):
+ def __init__(self, paths=None, asset=None, cache=True, location=None,
+ **kwargs):
"""
Loads all of the paths/urls specified (if any).
@@ -59,6 +62,25 @@ class AppriseAttachment(object):
It's also worth nothing that the cache value is only set to elements
that are not already of subclass AttachBase()
+
+ Optionally set your current ContentLocation in the location argument.
+ This is used to further handle attachments. The rules are as follows:
+ - INACCESSIBLE: You simply have disabled use of the object; no
+ attachments will be retrieved/handled.
+ - HOSTED: You are hosting an attachment service for others.
+ In these circumstances all attachments that are LOCAL
+ based (such as file://) will not be allowed.
+ - LOCAL: The least restrictive mode as local files can be
+ referenced in addition to hosted.
+
+ In all both HOSTED and LOCAL modes, INACCESSIBLE attachment types will
+ continue to be inaccessible. However if you set this field (location)
+ to None (it's default value) the attachment location category will not
+ be tested in any way (all attachment types will be allowed).
+
+ The location field is also a global option that can be set when
+ initializing the Apprise object.
+
"""
# Initialize our attachment listings
@@ -71,6 +93,15 @@ class AppriseAttachment(object):
self.asset = \
asset if isinstance(asset, AppriseAsset) else AppriseAsset()
+ if location is not None and location not in CONTENT_LOCATIONS:
+ msg = "An invalid Attachment location ({}) was specified." \
+ .format(location)
+ logger.warning(msg)
+ raise TypeError(msg)
+
+ # Store our location
+ self.location = location
+
# Now parse any paths specified
if paths is not None:
# Store our path(s)
@@ -123,26 +154,45 @@ class AppriseAttachment(object):
# Iterate over our attachments
for _attachment in attachments:
-
- if isinstance(_attachment, attachment.AttachBase):
- # Go ahead and just add our attachment into our list
- self.attachments.append(_attachment)
+ if self.location == ContentLocation.INACCESSIBLE:
+ logger.warning(
+ "Attachments are disabled; ignoring {}"
+ .format(_attachment))
+ return_status = False
continue
- elif not isinstance(_attachment, six.string_types):
+ if isinstance(_attachment, six.string_types):
+ logger.debug("Loading attachment: {}".format(_attachment))
+ # Instantiate ourselves an object, this function throws or
+ # returns None if it fails
+ instance = AppriseAttachment.instantiate(
+ _attachment, asset=asset, cache=cache)
+ if not isinstance(instance, attachment.AttachBase):
+ return_status = False
+ continue
+
+ elif not isinstance(_attachment, attachment.AttachBase):
logger.warning(
"An invalid attachment (type={}) was specified.".format(
type(_attachment)))
return_status = False
continue
- logger.debug("Loading attachment: {}".format(_attachment))
+ else:
+ # our entry is of type AttachBase, so just go ahead and point
+ # our instance to it for some post processing below
+ instance = _attachment
- # Instantiate ourselves an object, this function throws or
- # returns None if it fails
- instance = AppriseAttachment.instantiate(
- _attachment, asset=asset, cache=cache)
- if not isinstance(instance, attachment.AttachBase):
+ # Apply some simple logic if our location flag is set
+ if self.location and ((
+ self.location == ContentLocation.HOSTED
+ and instance.location != ContentLocation.HOSTED)
+ or instance.location == ContentLocation.INACCESSIBLE):
+ logger.warning(
+ "Attachment was disallowed due to accessibility "
+ "restrictions ({}->{}): {}".format(
+ self.location, instance.location,
+ instance.url(privacy=True)))
return_status = False
continue
diff --git a/libs/apprise/AppriseAttachment.pyi b/libs/apprise/AppriseAttachment.pyi
new file mode 100644
index 000000000..d68eccc13
--- /dev/null
+++ b/libs/apprise/AppriseAttachment.pyi
@@ -0,0 +1,38 @@
+from typing import Any, Iterable, Optional, Union
+
+from . import AppriseAsset, ContentLocation
+from .attachment import AttachBase
+
+_Attachment = Union[str, AttachBase]
+_Attachments = Iterable[_Attachment]
+
+class AppriseAttachment:
+ def __init__(
+ self,
+ paths: Optional[_Attachments] = ...,
+ asset: Optional[AppriseAttachment] = ...,
+ cache: bool = ...,
+ location: Optional[ContentLocation] = ...,
+ **kwargs: Any
+ ) -> None: ...
+ def add(
+ self,
+ attachments: _Attachments,
+ asset: Optional[AppriseAttachment] = ...,
+ cache: Optional[bool] = ...
+ ) -> bool: ...
+ @staticmethod
+ def instantiate(
+ url: str,
+ asset: Optional[AppriseAsset] = ...,
+ cache: Optional[bool] = ...,
+ suppress_exceptions: bool = ...
+ ) -> NotifyBase: ...
+ def clear(self) -> None: ...
+ def size(self) -> int: ...
+ def pop(self, index: int = ...) -> AttachBase: ...
+ def __getitem__(self, index: int) -> AttachBase: ...
+ def __bool__(self) -> bool: ...
+ def __nonzero__(self) -> bool: ...
+ def __iter__(self) -> Iterator[AttachBase]: ...
+ def __len__(self) -> int: ...
\ No newline at end of file
diff --git a/libs/apprise/AppriseConfig.pyi b/libs/apprise/AppriseConfig.pyi
new file mode 100644
index 000000000..36fa9c065
--- /dev/null
+++ b/libs/apprise/AppriseConfig.pyi
@@ -0,0 +1,49 @@
+from typing import Any, Iterable, Iterator, List, Optional, Union
+
+from . import AppriseAsset, NotifyBase
+from .config import ConfigBase
+
+_Configs = Union[ConfigBase, str, Iterable[str]]
+
+class AppriseConfig:
+ def __init__(
+ self,
+ paths: Optional[_Configs] = ...,
+ asset: Optional[AppriseAsset] = ...,
+ cache: bool = ...,
+ recursion: int = ...,
+ insecure_includes: bool = ...,
+ **kwargs: Any
+ ) -> None: ...
+ def add(
+ self,
+ configs: _Configs,
+ asset: Optional[AppriseAsset] = ...,
+ cache: bool = ...,
+ recursion: Optional[bool] = ...,
+ insecure_includes: Optional[bool] = ...
+ ) -> bool: ...
+ def add_config(
+ self,
+ content: str,
+ asset: Optional[AppriseAsset] = ...,
+ tag: Optional[str] = ...,
+ format: Optional[str] = ...,
+ recursion: Optional[int] = ...,
+ insecure_includes: Optional[bool] = ...
+ ) -> bool: ...
+ def servers(self, tag: str = ..., *args: Any, **kwargs: Any) -> List[ConfigBase]: ...
+ def instantiate(
+ url: str,
+ asset: Optional[AppriseAsset] = ...,
+ tag: Optional[str] = ...,
+ cache: Optional[bool] = ...
+ ) -> NotifyBase: ...
+ def clear(self) -> None: ...
+ def server_pop(self, index: int) -> ConfigBase: ...
+ def pop(self, index: int = ...) -> ConfigBase: ...
+ def __getitem__(self, index: int) -> ConfigBase: ...
+ def __bool__(self) -> bool: ...
+ def __nonzero__(self) -> bool: ...
+ def __iter__(self) -> Iterator[ConfigBase]: ...
+ def __len__(self) -> int: ...
\ No newline at end of file
diff --git a/libs/apprise/URLBase.py b/libs/apprise/URLBase.py
index 78109ae48..f5428dbb1 100644
--- a/libs/apprise/URLBase.py
+++ b/libs/apprise/URLBase.py
@@ -25,7 +25,7 @@
import re
import six
-import logging
+from .logger import logger
from time import sleep
from datetime import datetime
from xml.sax.saxutils import escape as sax_escape
@@ -47,6 +47,7 @@ from .AppriseAsset import AppriseAsset
from .utils import parse_url
from .utils import parse_bool
from .utils import parse_list
+from .utils import parse_phone_no
# Used to break a path list into parts
PATHSPLIT_LIST_DELIM = re.compile(r'[ \t\r\n,\\/]+')
@@ -115,8 +116,8 @@ class URLBase(object):
# Secure sites should be verified against a Certificate Authority
verify_certificate = True
- # Logging
- logger = logging.getLogger(__name__)
+ # Logging to our global logger
+ logger = logger
# Define a default set of template arguments used for dynamically building
# details about our individual plugins for developers.
@@ -280,7 +281,7 @@ class URLBase(object):
self._last_io_datetime = reference
return
- if self.request_rate_per_sec <= 0.0:
+ if self.request_rate_per_sec <= 0.0 and not wait:
# We're done if there is no throttle limit set
return
@@ -560,6 +561,39 @@ class URLBase(object):
return content
+ @staticmethod
+ def parse_phone_no(content, unquote=True):
+ """A wrapper to utils.parse_phone_no() with unquoting support
+
+ Parses a specified set of data and breaks it into a list.
+
+ Args:
+ content (str): The path to split up into a list. If a list is
+ provided, then it's individual entries are processed.
+
+ unquote (:obj:`bool`, optional): call unquote on each element
+ added to the returned list.
+
+ Returns:
+ list: A unique list containing all of the elements in the path
+ """
+
+ if unquote:
+ try:
+ content = URLBase.unquote(content)
+ except TypeError:
+ # Nothing further to do
+ return []
+
+ except AttributeError:
+ # This exception ONLY gets thrown under Python v2.7 if an
+ # object() is passed in place of the content
+ return []
+
+ content = parse_phone_no(content)
+
+ return content
+
@property
def app_id(self):
return self.asset.app_id if self.asset.app_id else ''
@@ -636,6 +670,8 @@ class URLBase(object):
results['qsd'].get('verify', True))
# Password overrides
+ if 'password' in results['qsd']:
+ results['password'] = results['qsd']['password']
if 'pass' in results['qsd']:
results['password'] = results['qsd']['pass']
diff --git a/libs/apprise/URLBase.pyi b/libs/apprise/URLBase.pyi
new file mode 100644
index 000000000..915885745
--- /dev/null
+++ b/libs/apprise/URLBase.pyi
@@ -0,0 +1,16 @@
+from logging import logger
+from typing import Any, Iterable, Set, Optional
+
+class URLBase:
+ service_name: Optional[str]
+ protocol: Optional[str]
+ secure_protocol: Optional[str]
+ request_rate_per_sec: int
+ socket_connect_timeout: float
+ socket_read_timeout: float
+ tags: Set[str]
+ verify_certificate: bool
+ logger: logger
+ def url(self, privacy: bool = ..., *args: Any, **kwargs: Any) -> str: ...
+ def __contains__(self, tags: Iterable[str]) -> bool: ...
+ def __str__(self) -> str: ...
\ No newline at end of file
diff --git a/libs/apprise/__init__.py b/libs/apprise/__init__.py
index a2511d286..090261086 100644
--- a/libs/apprise/__init__.py
+++ b/libs/apprise/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2020 Chris Caron
+# Copyright (C) 2021 Chris Caron
# All rights reserved.
#
# This code is licensed under the MIT License.
@@ -23,11 +23,11 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-__title__ = 'apprise'
-__version__ = '0.8.8'
+__title__ = 'Apprise'
+__version__ = '0.9.6'
__author__ = 'Chris Caron'
__license__ = 'MIT'
-__copywrite__ = 'Copyright (C) 2020 Chris Caron '
+__copywrite__ = 'Copyright (C) 2021 Chris Caron '
__email__ = 'lead2gold@gmail.com'
__status__ = 'Production'
@@ -41,8 +41,10 @@ from .common import OverflowMode
from .common import OVERFLOW_MODES
from .common import ConfigFormat
from .common import CONFIG_FORMATS
-from .common import ConfigIncludeMode
-from .common import CONFIG_INCLUDE_MODES
+from .common import ContentIncludeMode
+from .common import CONTENT_INCLUDE_MODES
+from .common import ContentLocation
+from .common import CONTENT_LOCATIONS
from .URLBase import URLBase
from .URLBase import PrivacyMode
@@ -55,10 +57,13 @@ from .AppriseAsset import AppriseAsset
from .AppriseConfig import AppriseConfig
from .AppriseAttachment import AppriseAttachment
+# Inherit our logging with our additional entries added to it
+from .logger import logging
+from .logger import logger
+from .logger import LogCapture
+
# Set default logging handler to avoid "No handler found" warnings.
-import logging
-from logging import NullHandler
-logging.getLogger(__name__).addHandler(NullHandler())
+logging.getLogger(__name__).addHandler(logging.NullHandler())
__all__ = [
# Core
@@ -69,6 +74,10 @@ __all__ = [
'NotifyType', 'NotifyImageSize', 'NotifyFormat', 'OverflowMode',
'NOTIFY_TYPES', 'NOTIFY_IMAGE_SIZES', 'NOTIFY_FORMATS', 'OVERFLOW_MODES',
'ConfigFormat', 'CONFIG_FORMATS',
- 'ConfigIncludeMode', 'CONFIG_INCLUDE_MODES',
+ 'ContentIncludeMode', 'CONTENT_INCLUDE_MODES',
+ 'ContentLocation', 'CONTENT_LOCATIONS',
'PrivacyMode',
+
+ # Logging
+ 'logging', 'logger', 'LogCapture',
]
diff --git a/libs/apprise/assets/NotifyXML-1.0.xsd b/libs/apprise/assets/NotifyXML-1.0.xsd
index d9b7235aa..0e3f8f130 100644
--- a/libs/apprise/assets/NotifyXML-1.0.xsd
+++ b/libs/apprise/assets/NotifyXML-1.0.xsd
@@ -1,22 +1,23 @@
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/apprise/assets/NotifyXML-1.1.xsd b/libs/apprise/assets/NotifyXML-1.1.xsd
new file mode 100644
index 000000000..cc6dbae65
--- /dev/null
+++ b/libs/apprise/assets/NotifyXML-1.1.xsd
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/apprise/attachment/AttachBase.py b/libs/apprise/attachment/AttachBase.py
index 1fde66f4b..aa7174fcf 100644
--- a/libs/apprise/attachment/AttachBase.py
+++ b/libs/apprise/attachment/AttachBase.py
@@ -28,6 +28,7 @@ import time
import mimetypes
from ..URLBase import URLBase
from ..utils import parse_bool
+from ..common import ContentLocation
from ..AppriseLocale import gettext_lazy as _
@@ -62,6 +63,11 @@ class AttachBase(URLBase):
# 5 MB = 5242880 bytes
max_file_size = 5242880
+ # By default all attachments types are inaccessible.
+ # Developers of items identified in the attachment plugin directory
+ # are requried to set a location
+ location = ContentLocation.INACCESSIBLE
+
# Here is where we define all of the arguments we accept on the url
# such as: schema://whatever/?overflow=upstream&format=text
# These act the same way as tokens except they are optional and/or
diff --git a/libs/apprise/attachment/AttachBase.pyi b/libs/apprise/attachment/AttachBase.pyi
new file mode 100644
index 000000000..9b8eb02a5
--- /dev/null
+++ b/libs/apprise/attachment/AttachBase.pyi
@@ -0,0 +1,37 @@
+from typing import Any, Dict, Optional
+
+from .. import ContentLocation
+
+class AttachBase:
+ max_detect_buffer_size: int
+ unknown_mimetype: str
+ unknown_filename: str
+ unknown_filename_extension: str
+ strict: bool
+ max_file_size: int
+ location: ContentLocation
+ template_args: Dict[str, Any]
+ def __init__(
+ self,
+ name: Optional[str] = ...,
+ mimetype: Optional[str] = ...,
+ cache: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+ @property
+ def path(self) -> Optional[str]: ...
+ @property
+ def name(self) -> Optional[str]: ...
+ @property
+ def mimetype(self) -> Optional[str]: ...
+ def exists(self) -> bool: ...
+ def invalidate(self) -> None: ...
+ def download(self) -> bool: ...
+ @staticmethod
+ def parse_url(
+ url: str,
+ verify_host: bool = ...
+ ) -> Dict[str, Any]: ...
+ def __len__(self) -> int: ...
+ def __bool__(self) -> bool: ...
+ def __nonzero__(self) -> bool: ...
\ No newline at end of file
diff --git a/libs/apprise/attachment/AttachFile.py b/libs/apprise/attachment/AttachFile.py
index a8609bd60..20ee15199 100644
--- a/libs/apprise/attachment/AttachFile.py
+++ b/libs/apprise/attachment/AttachFile.py
@@ -26,6 +26,7 @@
import re
import os
from .AttachBase import AttachBase
+from ..common import ContentLocation
from ..AppriseLocale import gettext_lazy as _
@@ -40,6 +41,10 @@ class AttachFile(AttachBase):
# The default protocol
protocol = 'file'
+ # Content is local to the same location as the apprise instance
+ # being called (server-side)
+ location = ContentLocation.LOCAL
+
def __init__(self, path, **kwargs):
"""
Initialize Local File Attachment Object
@@ -81,6 +86,10 @@ class AttachFile(AttachBase):
validate it.
"""
+ if self.location == ContentLocation.INACCESSIBLE:
+ # our content is inaccessible
+ return False
+
# Ensure any existing content set has been invalidated
self.invalidate()
diff --git a/libs/apprise/attachment/AttachHTTP.py b/libs/apprise/attachment/AttachHTTP.py
index d5396cf85..1d915ad3c 100644
--- a/libs/apprise/attachment/AttachHTTP.py
+++ b/libs/apprise/attachment/AttachHTTP.py
@@ -29,6 +29,7 @@ import six
import requests
from tempfile import NamedTemporaryFile
from .AttachBase import AttachBase
+from ..common import ContentLocation
from ..URLBase import PrivacyMode
from ..AppriseLocale import gettext_lazy as _
@@ -50,6 +51,9 @@ class AttachHTTP(AttachBase):
# The number of bytes in memory to read from the remote source at a time
chunk_size = 8192
+ # Web based requests are remote/external to our current location
+ location = ContentLocation.HOSTED
+
def __init__(self, headers=None, **kwargs):
"""
Initialize HTTP Object
@@ -86,6 +90,10 @@ class AttachHTTP(AttachBase):
Perform retrieval of the configuration based on the specified request
"""
+ if self.location == ContentLocation.INACCESSIBLE:
+ # our content is inaccessible
+ return False
+
# Ensure any existing content set has been invalidated
self.invalidate()
diff --git a/libs/apprise/cli.py b/libs/apprise/cli.py
index 690530000..70458c92d 100644
--- a/libs/apprise/cli.py
+++ b/libs/apprise/cli.py
@@ -26,7 +26,11 @@
import click
import logging
import platform
+import six
import sys
+import os
+import re
+
from os.path import isfile
from os.path import expanduser
from os.path import expandvars
@@ -39,6 +43,7 @@ from . import AppriseConfig
from .utils import parse_list
from .common import NOTIFY_TYPES
from .common import NOTIFY_FORMATS
+from .common import ContentLocation
from .logger import logger
from . import __title__
@@ -133,6 +138,9 @@ def print_version_msg():
help='Perform a trial run but only prints the notification '
'services to-be triggered to stdout. Notifications are never '
'sent using this mode.')
+@click.option('--details', '-l', is_flag=True,
+ help='Prints details about the current services supported by '
+ 'Apprise.')
@click.option('--recursion-depth', '-R', default=DEFAULT_RECURSION_DEPTH,
type=int,
help='The number of recursive import entries that can be '
@@ -141,6 +149,8 @@ def print_version_msg():
@click.option('--verbose', '-v', count=True,
help='Makes the operation more talkative. Use multiple v to '
'increase the verbosity. I.e.: -vvvv')
+@click.option('--interpret-escapes', '-e', is_flag=True,
+ help='Enable interpretation of backslash escapes')
@click.option('--debug', '-D', is_flag=True, help='Debug mode')
@click.option('--version', '-V', is_flag=True,
help='Display the apprise version and exit.')
@@ -148,7 +158,7 @@ def print_version_msg():
metavar='SERVER_URL [SERVER_URL2 [SERVER_URL3]]',)
def main(body, title, config, attach, urls, notification_type, theme, tag,
input_format, dry_run, recursion_depth, verbose, disable_async,
- debug, version):
+ details, interpret_escapes, debug, version):
"""
Send a notification to all of the specified servers identified by their
URLs the content provided within the title, body and notification-type.
@@ -224,8 +234,15 @@ def main(body, title, config, attach, urls, notification_type, theme, tag,
# Prepare our asset
asset = AppriseAsset(
+ # Our body format
body_format=input_format,
+
+ # Interpret Escapes
+ interpret_escapes=interpret_escapes,
+
+ # Set the theme
theme=theme,
+
# Async mode is only used for Python v3+ and allows a user to send
# all of their notifications asyncronously. This was made an option
# incase there are problems in the future where it's better that
@@ -234,18 +251,132 @@ def main(body, title, config, attach, urls, notification_type, theme, tag,
)
# Create our Apprise object
- a = Apprise(asset=asset, debug=debug)
+ a = Apprise(asset=asset, debug=debug, location=ContentLocation.LOCAL)
- # Load our configuration if no URLs or specified configuration was
- # identified on the command line
- a.add(AppriseConfig(
- paths=[f for f in DEFAULT_SEARCH_PATHS if isfile(expanduser(f))]
- if not (config or urls) else config,
- asset=asset, recursion=recursion_depth))
+ if details:
+ # Print details and exit
+ results = a.details(show_requirements=True, show_disabled=True)
- # Load our inventory up
- for url in urls:
- a.add(url)
+ # Sort our results:
+ plugins = sorted(
+ results['schemas'], key=lambda i: str(i['service_name']))
+ for entry in plugins:
+ protocols = [] if not entry['protocols'] else \
+ [p for p in entry['protocols']
+ if isinstance(p, six.string_types)]
+ protocols.extend(
+ [] if not entry['secure_protocols'] else
+ [p for p in entry['secure_protocols']
+ if isinstance(p, six.string_types)])
+
+ if len(protocols) == 1:
+ # Simplify view by swapping {schema} with the single
+ # protocol value
+
+ # Convert tuple to list
+ entry['details']['templates'] = \
+ list(entry['details']['templates'])
+
+ for x in range(len(entry['details']['templates'])):
+ entry['details']['templates'][x] = \
+ re.sub(
+ r'^[^}]+}://',
+ '{}://'.format(protocols[0]),
+ entry['details']['templates'][x])
+
+ click.echo(click.style(
+ '{} {:<30} '.format(
+ '+' if entry['enabled'] else '-',
+ str(entry['service_name'])),
+ fg="green" if entry['enabled'] else "red", bold=True),
+ nl=(not entry['enabled'] or len(protocols) == 1))
+
+ if not entry['enabled']:
+ if entry['requirements']['details']:
+ click.echo(
+ ' ' + str(entry['requirements']['details']))
+
+ if entry['requirements']['packages_required']:
+ click.echo(' Python Packages Required:')
+ for req in entry['requirements']['packages_required']:
+ click.echo(' - ' + req)
+
+ if entry['requirements']['packages_recommended']:
+ click.echo(' Python Packages Recommended:')
+ for req in entry['requirements']['packages_recommended']:
+ click.echo(' - ' + req)
+
+ # new line padding between entries
+ click.echo()
+ continue
+
+ if len(protocols) > 1:
+ click.echo('| Schema(s): {}'.format(
+ ', '.join(protocols),
+ ))
+
+ prefix = ' - '
+ click.echo('{}{}'.format(
+ prefix,
+ '\n{}'.format(prefix).join(entry['details']['templates'])))
+
+ # new line padding between entries
+ click.echo()
+
+ sys.exit(0)
+
+ # The priorities of what is accepted are parsed in order below:
+ # 1. URLs by command line
+ # 2. Configuration by command line
+ # 3. URLs by environment variable: APPRISE_URLS
+ # 4. Configuration by environment variable: APPRISE_CONFIG
+ # 5. Default Configuration File(s) (if found)
+ #
+ if urls:
+ if tag:
+ # Ignore any tags specified
+ logger.warning(
+ '--tag (-g) entries are ignored when using specified URLs')
+ tag = None
+
+ # Load our URLs (if any defined)
+ for url in urls:
+ a.add(url)
+
+ if config:
+ # Provide a warning to the end user if they specified both
+ logger.warning(
+ 'You defined both URLs and a --config (-c) entry; '
+ 'Only the URLs will be referenced.')
+
+ elif config:
+ # We load our configuration file(s) now only if no URLs were specified
+ # Specified config entries trump all
+ a.add(AppriseConfig(
+ paths=config, asset=asset, recursion=recursion_depth))
+
+ elif os.environ.get('APPRISE_URLS', '').strip():
+ logger.debug('Loading provided APPRISE_URLS environment variable')
+ if tag:
+ # Ignore any tags specified
+ logger.warning(
+ '--tag (-g) entries are ignored when using specified URLs')
+ tag = None
+
+ # Attempt to use our APPRISE_URLS environment variable (if populated)
+ a.add(os.environ['APPRISE_URLS'].strip())
+
+ elif os.environ.get('APPRISE_CONFIG', '').strip():
+ logger.debug('Loading provided APPRISE_CONFIG environment variable')
+ # Fall back to config environment variable (if populated)
+ a.add(AppriseConfig(
+ paths=os.environ['APPRISE_CONFIG'].strip(),
+ asset=asset, recursion=recursion_depth))
+ else:
+ # Load default configuration
+ a.add(AppriseConfig(
+ paths=[f for f in DEFAULT_SEARCH_PATHS if isfile(expanduser(f))],
+ asset=asset, recursion=recursion_depth))
if len(a) == 0:
logger.error(
diff --git a/libs/apprise/common.py b/libs/apprise/common.py
index 329b5d93f..186bfe1bc 100644
--- a/libs/apprise/common.py
+++ b/libs/apprise/common.py
@@ -130,28 +130,58 @@ CONFIG_FORMATS = (
)
-class ConfigIncludeMode(object):
+class ContentIncludeMode(object):
"""
- The different Cofiguration inclusion modes. All Configuration
- plugins will have one of these associated with it.
+ The different Content inclusion modes. All content based plugins will
+ have one of these associated with it.
"""
- # - Configuration inclusion of same type only; hence a file:// can include
+ # - Content inclusion of same type only; hence a file:// can include
# a file://
# - Cross file inclusion is not allowed unless insecure_includes (a flag)
# is set to True. In these cases STRICT acts as type ALWAYS
STRICT = 'strict'
- # This configuration type can never be included
+ # This content type can never be included
NEVER = 'never'
- # File configuration can always be included
+ # This content can always be included
ALWAYS = 'always'
-CONFIG_INCLUDE_MODES = (
- ConfigIncludeMode.STRICT,
- ConfigIncludeMode.NEVER,
- ConfigIncludeMode.ALWAYS,
+CONTENT_INCLUDE_MODES = (
+ ContentIncludeMode.STRICT,
+ ContentIncludeMode.NEVER,
+ ContentIncludeMode.ALWAYS,
+)
+
+
+class ContentLocation(object):
+ """
+ This is primarily used for handling file attachments. The idea is
+ to track the source of the attachment itself. We don't want
+ remote calls to a server to access local attachments for example.
+
+ By knowing the attachment type and cross-associating it with how
+ we plan on accessing the content, we can make a judgement call
+ (for security reasons) if we will allow it.
+
+ Obviously local uses of apprise can access both local and remote
+ type files.
+ """
+ # Content is located locally (on the same server as apprise)
+ LOCAL = 'local'
+
+ # Content is located in a remote location
+ HOSTED = 'hosted'
+
+ # Content is inaccessible
+ INACCESSIBLE = 'n/a'
+
+
+CONTENT_LOCATIONS = (
+ ContentLocation.LOCAL,
+ ContentLocation.HOSTED,
+ ContentLocation.INACCESSIBLE,
)
# This is a reserved tag that is automatically assigned to every
diff --git a/libs/apprise/common.pyi b/libs/apprise/common.pyi
new file mode 100644
index 000000000..769573185
--- /dev/null
+++ b/libs/apprise/common.pyi
@@ -0,0 +1,15 @@
+class NotifyType:
+ INFO: NotifyType
+ SUCCESS: NotifyType
+ WARNING: NotifyType
+ FAILURE: NotifyType
+
+class NotifyFormat:
+ TEXT: NotifyFormat
+ HTML: NotifyFormat
+ MARKDOWN: NotifyFormat
+
+class ContentLocation:
+ LOCAL: ContentLocation
+ HOSTED: ContentLocation
+ INACCESSIBLE: ContentLocation
\ No newline at end of file
diff --git a/libs/apprise/config/ConfigBase.py b/libs/apprise/config/ConfigBase.py
index 22efd8e29..f2b958ed8 100644
--- a/libs/apprise/config/ConfigBase.py
+++ b/libs/apprise/config/ConfigBase.py
@@ -34,13 +34,18 @@ from ..AppriseAsset import AppriseAsset
from ..URLBase import URLBase
from ..common import ConfigFormat
from ..common import CONFIG_FORMATS
-from ..common import ConfigIncludeMode
+from ..common import ContentIncludeMode
from ..utils import GET_SCHEMA_RE
from ..utils import parse_list
from ..utils import parse_bool
from ..utils import parse_urls
+from ..utils import cwe312_url
from . import SCHEMA_MAP
+# Test whether token is valid or not
+VALID_TOKEN = re.compile(
+ r'(?P[a-z0-9][a-z0-9_]+)', re.I)
+
class ConfigBase(URLBase):
"""
@@ -65,7 +70,7 @@ class ConfigBase(URLBase):
# By default all configuration is not includable using the 'include'
# line found in configuration files.
- allow_cross_includes = ConfigIncludeMode.NEVER
+ allow_cross_includes = ContentIncludeMode.NEVER
# the config path manages the handling of relative include
config_path = os.getcwd()
@@ -205,8 +210,8 @@ class ConfigBase(URLBase):
# Configuration files were detected; recursively populate them
# If we have been configured to do so
for url in configs:
- if self.recursion > 0:
+ if self.recursion > 0:
# Attempt to acquire the schema at the very least to allow
# our configuration based urls.
schema = GET_SCHEMA_RE.match(url)
@@ -219,6 +224,7 @@ class ConfigBase(URLBase):
url = os.path.join(self.config_path, url)
url = '{}://{}'.format(schema, URLBase.quote(url))
+
else:
# Ensure our schema is always in lower case
schema = schema.group('schema').lower()
@@ -229,27 +235,31 @@ class ConfigBase(URLBase):
'Unsupported include schema {}.'.format(schema))
continue
+ # CWE-312 (Secure Logging) Handling
+ loggable_url = url if not asset.secure_logging \
+ else cwe312_url(url)
+
# Parse our url details of the server object as dictionary
# containing all of the information parsed from our URL
results = SCHEMA_MAP[schema].parse_url(url)
if not results:
# Failed to parse the server URL
self.logger.warning(
- 'Unparseable include URL {}'.format(url))
+ 'Unparseable include URL {}'.format(loggable_url))
continue
# Handle cross inclusion based on allow_cross_includes rules
if (SCHEMA_MAP[schema].allow_cross_includes ==
- ConfigIncludeMode.STRICT
+ ContentIncludeMode.STRICT
and schema not in self.schemas()
and not self.insecure_includes) or \
SCHEMA_MAP[schema].allow_cross_includes == \
- ConfigIncludeMode.NEVER:
+ ContentIncludeMode.NEVER:
# Prevent the loading if insecure base protocols
ConfigBase.logger.warning(
'Including {}:// based configuration is prohibited. '
- 'Ignoring URL {}'.format(schema, url))
+ 'Ignoring URL {}'.format(schema, loggable_url))
continue
# Prepare our Asset Object
@@ -275,7 +285,7 @@ class ConfigBase(URLBase):
except Exception as e:
# the arguments are invalid or can not be used.
self.logger.warning(
- 'Could not load include URL: {}'.format(url))
+ 'Could not load include URL: {}'.format(loggable_url))
self.logger.debug('Loading Exception: {}'.format(str(e)))
continue
@@ -288,16 +298,23 @@ class ConfigBase(URLBase):
del cfg_plugin
else:
+ # CWE-312 (Secure Logging) Handling
+ loggable_url = url if not asset.secure_logging \
+ else cwe312_url(url)
+
self.logger.debug(
- 'Recursion limit reached; ignoring Include URL: %s' % url)
+ 'Recursion limit reached; ignoring Include URL: %s',
+ loggable_url)
if self._cached_servers:
- self.logger.info('Loaded {} entries from {}'.format(
- len(self._cached_servers), self.url()))
+ self.logger.info(
+ 'Loaded {} entries from {}'.format(
+ len(self._cached_servers),
+ self.url(privacy=asset.secure_logging)))
else:
self.logger.warning(
'Failed to load Apprise configuration from {}'.format(
- self.url()))
+ self.url(privacy=asset.secure_logging)))
# Set the time our content was cached at
self._cached_time = time.time()
@@ -527,6 +544,9 @@ class ConfigBase(URLBase):
# the include keyword
configs = list()
+ # Prepare our Asset Object
+ asset = asset if isinstance(asset, AppriseAsset) else AppriseAsset()
+
# Define what a valid line should look like
valid_line_re = re.compile(
r'^\s*(?P([;#]+(?P.*))|'
@@ -563,27 +583,37 @@ class ConfigBase(URLBase):
continue
if config:
- ConfigBase.logger.debug('Include URL: {}'.format(config))
+ # CWE-312 (Secure Logging) Handling
+ loggable_url = config if not asset.secure_logging \
+ else cwe312_url(config)
+
+ ConfigBase.logger.debug(
+ 'Include URL: {}'.format(loggable_url))
# Store our include line
configs.append(config.strip())
continue
+ # CWE-312 (Secure Logging) Handling
+ loggable_url = url if not asset.secure_logging \
+ else cwe312_url(url)
+
# Acquire our url tokens
- results = plugins.url_to_dict(url)
+ results = plugins.url_to_dict(
+ url, secure_logging=asset.secure_logging)
if results is None:
# Failed to parse the server URL
ConfigBase.logger.warning(
- 'Unparseable URL {} on line {}.'.format(url, line))
+ 'Unparseable URL {} on line {}.'.format(
+ loggable_url, line))
continue
# Build a list of tags to associate with the newly added
# notifications if any were set
results['tag'] = set(parse_list(result.group('tags')))
- # Prepare our Asset Object
- results['asset'] = \
- asset if isinstance(asset, AppriseAsset) else AppriseAsset()
+ # Set our Asset Object
+ results['asset'] = asset
try:
# Attempt to create an instance of our plugin using the
@@ -591,13 +621,14 @@ class ConfigBase(URLBase):
plugin = plugins.SCHEMA_MAP[results['schema']](**results)
# Create log entry of loaded URL
- ConfigBase.logger.debug('Loaded URL: {}'.format(plugin.url()))
+ ConfigBase.logger.debug(
+ 'Loaded URL: %s', plugin.url(privacy=asset.secure_logging))
except Exception as e:
# the arguments are invalid or can not be used.
ConfigBase.logger.warning(
'Could not load URL {} on line {}.'.format(
- url, line))
+ loggable_url, line))
ConfigBase.logger.debug('Loading Exception: %s' % str(e))
continue
@@ -633,7 +664,9 @@ class ConfigBase(URLBase):
# Load our data (safely)
result = yaml.load(content, Loader=yaml.SafeLoader)
- except (AttributeError, yaml.error.MarkedYAMLError) as e:
+ except (AttributeError,
+ yaml.parser.ParserError,
+ yaml.error.MarkedYAMLError) as e:
# Invalid content
ConfigBase.logger.error(
'Invalid Apprise YAML data specified.')
@@ -671,7 +704,9 @@ class ConfigBase(URLBase):
continue
if not (hasattr(asset, k) and
- isinstance(getattr(asset, k), six.string_types)):
+ isinstance(getattr(asset, k),
+ (bool, six.string_types))):
+
# We can't set a function or non-string set value
ConfigBase.logger.warning(
'Invalid asset key "{}".'.format(k))
@@ -681,15 +716,23 @@ class ConfigBase(URLBase):
# Convert to an empty string
v = ''
- if not isinstance(v, six.string_types):
+ if (isinstance(v, (bool, six.string_types))
+ and isinstance(getattr(asset, k), bool)):
+
+ # If the object in the Asset is a boolean, then
+ # we want to convert the specified string to
+ # match that.
+ setattr(asset, k, parse_bool(v))
+
+ elif isinstance(v, six.string_types):
+ # Set our asset object with the new value
+ setattr(asset, k, v.strip())
+
+ else:
# we must set strings with a string
ConfigBase.logger.warning(
'Invalid asset value to "{}".'.format(k))
continue
-
- # Set our asset object with the new value
- setattr(asset, k, v.strip())
-
#
# global tag root directive
#
@@ -740,6 +783,10 @@ class ConfigBase(URLBase):
# we can. Reset it to None on each iteration
results = list()
+ # CWE-312 (Secure Logging) Handling
+ loggable_url = url if not asset.secure_logging \
+ else cwe312_url(url)
+
if isinstance(url, six.string_types):
# We're just a simple URL string...
schema = GET_SCHEMA_RE.match(url)
@@ -748,16 +795,18 @@ class ConfigBase(URLBase):
# config file at least has something to take action
# with.
ConfigBase.logger.warning(
- 'Invalid URL {}, entry #{}'.format(url, no + 1))
+ 'Invalid URL {}, entry #{}'.format(
+ loggable_url, no + 1))
continue
# We found a valid schema worthy of tracking; store it's
# details:
- _results = plugins.url_to_dict(url)
+ _results = plugins.url_to_dict(
+ url, secure_logging=asset.secure_logging)
if _results is None:
ConfigBase.logger.warning(
'Unparseable URL {}, entry #{}'.format(
- url, no + 1))
+ loggable_url, no + 1))
continue
# add our results to our global set
@@ -791,19 +840,20 @@ class ConfigBase(URLBase):
.format(key, no + 1))
continue
- # Store our URL and Schema Regex
- _url = key
-
# Store our schema
schema = _schema.group('schema').lower()
+ # Store our URL and Schema Regex
+ _url = key
+
if _url is None:
# the loop above failed to match anything
ConfigBase.logger.warning(
- 'Unsupported schema in urls, entry #{}'.format(no + 1))
+ 'Unsupported URL, entry #{}'.format(no + 1))
continue
- _results = plugins.url_to_dict(_url)
+ _results = plugins.url_to_dict(
+ _url, secure_logging=asset.secure_logging)
if _results is None:
# Setup dictionary
_results = {
@@ -830,12 +880,33 @@ class ConfigBase(URLBase):
if 'schema' in entries:
del entries['schema']
+ # support our special tokens (if they're present)
+ if schema in plugins.SCHEMA_MAP:
+ entries = ConfigBase._special_token_handler(
+ schema, entries)
+
# Extend our dictionary with our new entries
r.update(entries)
# add our results to our global set
results.append(r)
+ elif isinstance(tokens, dict):
+ # support our special tokens (if they're present)
+ if schema in plugins.SCHEMA_MAP:
+ tokens = ConfigBase._special_token_handler(
+ schema, tokens)
+
+ # Copy ourselves a template of our parsed URL as a base to
+ # work with
+ r = _results.copy()
+
+ # add our result set
+ r.update(tokens)
+
+ # add our results to our global set
+ results.append(r)
+
else:
# add our results to our global set
results.append(_results)
@@ -867,6 +938,17 @@ class ConfigBase(URLBase):
# Just use the global settings
_results['tag'] = global_tags
+ for key in list(_results.keys()):
+ # Strip out any tokens we know that we can't accept and
+ # warn the user
+ match = VALID_TOKEN.match(key)
+ if not match:
+ ConfigBase.logger.warning(
+ 'Ignoring invalid token ({}) found in YAML '
+ 'configuration entry #{}, item #{}'
+ .format(key, no + 1, entry))
+ del _results[key]
+
ConfigBase.logger.trace(
'URL #{}: {} unpacked as:{}{}'
.format(no + 1, url, os.linesep, os.linesep.join(
@@ -883,7 +965,8 @@ class ConfigBase(URLBase):
# Create log entry of loaded URL
ConfigBase.logger.debug(
- 'Loaded URL: {}'.format(plugin.url()))
+ 'Loaded URL: {}'.format(
+ plugin.url(privacy=asset.secure_logging)))
except Exception as e:
# the arguments are invalid or can not be used.
@@ -913,6 +996,135 @@ class ConfigBase(URLBase):
# Pop the element off of the stack
return self._cached_servers.pop(index)
+ @staticmethod
+ def _special_token_handler(schema, tokens):
+ """
+ This function takes a list of tokens and updates them to no longer
+ include any special tokens such as +,-, and :
+
+ - schema must be a valid schema of a supported plugin type
+ - tokens must be a dictionary containing the yaml entries parsed.
+
+ The idea here is we can post process a set of tokens provided in
+ a YAML file where the user provided some of the special keywords.
+
+ We effectivley look up what these keywords map to their appropriate
+ value they're expected
+ """
+ # Create a copy of our dictionary
+ tokens = tokens.copy()
+
+ for kw, meta in plugins.SCHEMA_MAP[schema]\
+ .template_kwargs.items():
+
+ # Determine our prefix:
+ prefix = meta.get('prefix', '+')
+
+ # Detect any matches
+ matches = \
+ {k[1:]: str(v) for k, v in tokens.items()
+ if k.startswith(prefix)}
+
+ if not matches:
+ # we're done with this entry
+ continue
+
+ if not isinstance(tokens.get(kw), dict):
+ # Invalid; correct it
+ tokens[kw] = dict()
+
+ # strip out processed tokens
+ tokens = {k: v for k, v in tokens.items()
+ if not k.startswith(prefix)}
+
+ # Update our entries
+ tokens[kw].update(matches)
+
+ # Now map our tokens accordingly to the class templates defined by
+ # each service.
+ #
+ # This is specifically used for YAML file parsing. It allows a user to
+ # define an entry such as:
+ #
+ # urls:
+ # - mailto://user:pass@domain:
+ # - to: user1@hotmail.com
+ # - to: user2@hotmail.com
+ #
+ # Under the hood, the NotifyEmail() class does not parse the `to`
+ # argument. It's contents needs to be mapped to `targets`. This is
+ # defined in the class via the `template_args` and template_tokens`
+ # section.
+ #
+ # This function here allows these mappings to take place within the
+ # YAML file as independant arguments.
+ class_templates = \
+ plugins.details(plugins.SCHEMA_MAP[schema])
+
+ for key in list(tokens.keys()):
+
+ if key not in class_templates['args']:
+ # No need to handle non-arg entries
+ continue
+
+ # get our `map_to` and/or 'alias_of' value (if it exists)
+ map_to = class_templates['args'][key].get(
+ 'alias_of', class_templates['args'][key].get('map_to', ''))
+
+ if map_to == key:
+ # We're already good as we are now
+ continue
+
+ if map_to in class_templates['tokens']:
+ meta = class_templates['tokens'][map_to]
+
+ else:
+ meta = class_templates['args'].get(
+ map_to, class_templates['args'][key])
+
+ # Perform a translation/mapping if our code reaches here
+ value = tokens[key]
+ del tokens[key]
+
+ # Detect if we're dealign with a list or not
+ is_list = re.search(
+ r'^(list|choice):.*',
+ meta.get('type'),
+ re.IGNORECASE)
+
+ if map_to not in tokens:
+ tokens[map_to] = [] if is_list \
+ else meta.get('default')
+
+ elif is_list and not isinstance(tokens.get(map_to), list):
+ # Convert ourselves to a list if we aren't already
+ tokens[map_to] = [tokens[map_to]]
+
+ # Type Conversion
+ if re.search(
+ r'^(choice:)?string',
+ meta.get('type'),
+ re.IGNORECASE) \
+ and not isinstance(value, six.string_types):
+
+ # Ensure our format is as expected
+ value = str(value)
+
+ # Apply any further translations if required (absolute map)
+ # This is the case when an arg maps to a token which further
+ # maps to a different function arg on the class constructor
+ abs_map = meta.get('map_to', map_to)
+
+ # Set our token as how it was provided by the configuration
+ if isinstance(tokens.get(map_to), list):
+ tokens[abs_map].append(value)
+
+ else:
+ tokens[abs_map] = value
+
+ # Return our tokens
+ return tokens
+
def __getitem__(self, index):
"""
Returns the indexed server entry associated with the loaded
diff --git a/libs/apprise/config/ConfigBase.pyi b/libs/apprise/config/ConfigBase.pyi
new file mode 100644
index 000000000..abff1204d
--- /dev/null
+++ b/libs/apprise/config/ConfigBase.pyi
@@ -0,0 +1,3 @@
+from .. import URLBase
+
+class ConfigBase(URLBase): ...
\ No newline at end of file
diff --git a/libs/apprise/config/ConfigFile.py b/libs/apprise/config/ConfigFile.py
index 9f8102253..6fd1ecb23 100644
--- a/libs/apprise/config/ConfigFile.py
+++ b/libs/apprise/config/ConfigFile.py
@@ -28,7 +28,7 @@ import io
import os
from .ConfigBase import ConfigBase
from ..common import ConfigFormat
-from ..common import ConfigIncludeMode
+from ..common import ContentIncludeMode
from ..AppriseLocale import gettext_lazy as _
@@ -44,7 +44,7 @@ class ConfigFile(ConfigBase):
protocol = 'file'
# Configuration file inclusion can only be of the same type
- allow_cross_includes = ConfigIncludeMode.STRICT
+ allow_cross_includes = ContentIncludeMode.STRICT
def __init__(self, path, **kwargs):
"""
diff --git a/libs/apprise/config/ConfigHTTP.py b/libs/apprise/config/ConfigHTTP.py
index c4ad29425..88352733c 100644
--- a/libs/apprise/config/ConfigHTTP.py
+++ b/libs/apprise/config/ConfigHTTP.py
@@ -28,7 +28,7 @@ import six
import requests
from .ConfigBase import ConfigBase
from ..common import ConfigFormat
-from ..common import ConfigIncludeMode
+from ..common import ContentIncludeMode
from ..URLBase import PrivacyMode
from ..AppriseLocale import gettext_lazy as _
@@ -66,7 +66,7 @@ class ConfigHTTP(ConfigBase):
max_error_buffer_size = 2048
# Configuration file inclusion can always include this type
- allow_cross_includes = ConfigIncludeMode.ALWAYS
+ allow_cross_includes = ContentIncludeMode.ALWAYS
def __init__(self, headers=None, **kwargs):
"""
diff --git a/libs/apprise/i18n/apprise.pot b/libs/apprise/i18n/apprise.pot
index 2a0dc5e0a..274b379c1 100644
--- a/libs/apprise/i18n/apprise.pot
+++ b/libs/apprise/i18n/apprise.pot
@@ -1,21 +1,27 @@
# Translations template for apprise.
-# Copyright (C) 2020 Chris Caron
+# Copyright (C) 2021 Chris Caron
# This file is distributed under the same license as the apprise project.
-# FIRST AUTHOR , 2020.
+# FIRST AUTHOR , 2021.
#
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: apprise 0.8.8\n"
+"Project-Id-Version: apprise 0.9.6\n"
"Report-Msgid-Bugs-To: lead2gold@gmail.com\n"
-"POT-Creation-Date: 2020-09-02 07:46-0400\n"
+"POT-Creation-Date: 2021-12-01 18:56-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.7.0\n"
+"Generated-By: Babel 2.9.1\n"
+
+msgid "A local Gnome environment is required."
+msgstr ""
+
+msgid "A local Microsoft Windows environment is required."
+msgstr ""
msgid "API Key"
msgstr ""
@@ -44,6 +50,27 @@ msgstr ""
msgid "Add Tokens"
msgstr ""
+msgid "Alert Type"
+msgstr ""
+
+msgid "Alias"
+msgstr ""
+
+msgid "Amount"
+msgstr ""
+
+msgid "App Access Token"
+msgstr ""
+
+msgid "App ID"
+msgstr ""
+
+msgid "App Version"
+msgstr ""
+
+msgid "Application ID"
+msgstr ""
+
msgid "Application Key"
msgstr ""
@@ -83,6 +110,9 @@ msgstr ""
msgid "Cache Results"
msgstr ""
+msgid "Call"
+msgstr ""
+
msgid "Carbon Copy"
msgstr ""
@@ -104,15 +134,27 @@ msgstr ""
msgid "Country"
msgstr ""
+msgid "Currency"
+msgstr ""
+
msgid "Custom Icon"
msgstr ""
msgid "Cycles"
msgstr ""
+msgid "DBus Notification"
+msgstr ""
+
+msgid "Details"
+msgstr ""
+
msgid "Detect Bot Owner"
msgstr ""
+msgid "Device"
+msgstr ""
+
msgid "Device API Key"
msgstr ""
@@ -134,12 +176,18 @@ msgstr ""
msgid "Email"
msgstr ""
+msgid "Email Header"
+msgstr ""
+
msgid "Encrypted Password"
msgstr ""
msgid "Encrypted Salt"
msgstr ""
+msgid "Entity"
+msgstr ""
+
msgid "Event"
msgstr ""
@@ -152,6 +200,12 @@ msgstr ""
msgid "Facility"
msgstr ""
+msgid "Flair ID"
+msgstr ""
+
+msgid "Flair Text"
+msgstr ""
+
msgid "Footer Logo"
msgstr ""
@@ -170,6 +224,9 @@ msgstr ""
msgid "From Phone No"
msgstr ""
+msgid "Gnome Notification"
+msgstr ""
+
msgid "Group"
msgstr ""
@@ -185,12 +242,33 @@ msgstr ""
msgid "Icon Type"
msgstr ""
+msgid "Identifier"
+msgstr ""
+
+msgid "Image Link"
+msgstr ""
+
msgid "Include Footer"
msgstr ""
msgid "Include Image"
msgstr ""
+msgid "Include Segment"
+msgstr ""
+
+msgid "Is Ad?"
+msgstr ""
+
+msgid "Is Spoiler"
+msgstr ""
+
+msgid "Kind"
+msgstr ""
+
+msgid "Language"
+msgstr ""
+
msgid "Local File"
msgstr ""
@@ -200,6 +278,15 @@ msgstr ""
msgid "Log to STDERR"
msgstr ""
+msgid "Long-Lived Access Token"
+msgstr ""
+
+msgid "MacOSX Notification"
+msgstr ""
+
+msgid "Master Key"
+msgstr ""
+
msgid "Memory"
msgstr ""
@@ -209,18 +296,41 @@ msgstr ""
msgid "Message Mode"
msgstr ""
+msgid "Message Type"
+msgstr ""
+
msgid "Modal"
msgstr ""
msgid "Mode"
msgstr ""
+msgid "NSFW"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "No dependencies."
+msgstr ""
+
+msgid "Notification ID"
+msgstr ""
+
msgid "Notify Format"
msgstr ""
msgid "OAuth Access Token"
msgstr ""
+msgid "OAuth2 KeyFile"
+msgstr ""
+
+msgid ""
+"Only works with Mac OS X 10.8 and higher. Additionally requires that "
+"/usr/local/bin/terminal-notifier is locally accessible."
+msgstr ""
+
msgid "Organization"
msgstr ""
@@ -230,6 +340,12 @@ msgstr ""
msgid "Overflow Mode"
msgstr ""
+msgid "Packages are recommended to improve functionality."
+msgstr ""
+
+msgid "Packages are required to function."
+msgstr ""
+
msgid "Password"
msgstr ""
@@ -254,6 +370,9 @@ msgstr ""
msgid "Provider Key"
msgstr ""
+msgid "QOS"
+msgstr ""
+
msgid "Region"
msgstr ""
@@ -263,6 +382,9 @@ msgstr ""
msgid "Remove Tokens"
msgstr ""
+msgid "Resubmit Flag"
+msgstr ""
+
msgid "Retry"
msgstr ""
@@ -287,6 +409,9 @@ msgstr ""
msgid "Secure Mode"
msgstr ""
+msgid "Send Replies"
+msgstr ""
+
msgid "Sender ID"
msgstr ""
@@ -296,6 +421,9 @@ msgstr ""
msgid "Server Timeout"
msgstr ""
+msgid "Silent Notification"
+msgstr ""
+
msgid "Socket Connect Timeout"
msgstr ""
@@ -305,6 +433,9 @@ msgstr ""
msgid "Sound"
msgstr ""
+msgid "Sound Link"
+msgstr ""
+
msgid "Source Email"
msgstr ""
@@ -314,12 +445,21 @@ msgstr ""
msgid "Source Phone No"
msgstr ""
+msgid "Special Text Color"
+msgstr ""
+
msgid "Sticky"
msgstr ""
msgid "Subtitle"
msgstr ""
+msgid "Syslog Mode"
+msgstr ""
+
+msgid "Tags"
+msgstr ""
+
msgid "Target Channel"
msgstr ""
@@ -344,24 +484,45 @@ msgstr ""
msgid "Target Encoded ID"
msgstr ""
+msgid "Target Escalation"
+msgstr ""
+
msgid "Target JID"
msgstr ""
msgid "Target Phone No"
msgstr ""
+msgid "Target Player ID"
+msgstr ""
+
+msgid "Target Queue"
+msgstr ""
+
msgid "Target Room Alias"
msgstr ""
msgid "Target Room ID"
msgstr ""
+msgid "Target Schedule"
+msgstr ""
+
msgid "Target Short Code"
msgstr ""
+msgid "Target Stream"
+msgstr ""
+
+msgid "Target Subreddit"
+msgstr ""
+
msgid "Target Tag ID"
msgstr ""
+msgid "Target Team"
+msgstr ""
+
msgid "Target Topic"
msgstr ""
@@ -371,12 +532,24 @@ msgstr ""
msgid "Targets"
msgstr ""
+msgid "Targets "
+msgstr ""
+
+msgid "Team Name"
+msgstr ""
+
msgid "Template"
msgstr ""
msgid "Template Data"
msgstr ""
+msgid "Template Path"
+msgstr ""
+
+msgid "Template Tokens"
+msgstr ""
+
msgid "Tenant Domain"
msgstr ""
@@ -404,12 +577,27 @@ msgstr ""
msgid "Token C"
msgstr ""
+msgid "URL"
+msgstr ""
+
+msgid "URL Title"
+msgstr ""
+
msgid "Urgency"
msgstr ""
msgid "Use Avatar"
msgstr ""
+msgid "Use Blocks"
+msgstr ""
+
+msgid "Use Fields"
+msgstr ""
+
+msgid "Use Session"
+msgstr ""
+
msgid "User ID"
msgstr ""
@@ -434,18 +622,27 @@ msgstr ""
msgid "Web Based"
msgstr ""
+msgid "Web Page Preview"
+msgstr ""
+
msgid "Webhook"
msgstr ""
msgid "Webhook ID"
msgstr ""
+msgid "Webhook Key"
+msgstr ""
+
msgid "Webhook Mode"
msgstr ""
msgid "Webhook Token"
msgstr ""
+msgid "Workspace"
+msgstr ""
+
msgid "X-Axis"
msgstr ""
@@ -455,6 +652,9 @@ msgstr ""
msgid "Y-Axis"
msgstr ""
+msgid "libdbus-1.so.x must be installed."
+msgstr ""
+
msgid "ttl"
msgstr ""
diff --git a/libs/apprise/logger.py b/libs/apprise/logger.py
index c09027dff..082178129 100644
--- a/libs/apprise/logger.py
+++ b/libs/apprise/logger.py
@@ -23,7 +23,12 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
+import os
import logging
+from io import StringIO
+
+# The root identifier needed to monitor 'apprise' logging
+LOGGER_NAME = 'apprise'
# Define a verbosity level that is a noisier then debug mode
logging.TRACE = logging.DEBUG - 1
@@ -57,5 +62,136 @@ def deprecate(self, message, *args, **kwargs):
logging.Logger.trace = trace
logging.Logger.deprecate = deprecate
-# Create ourselve a generic logging reference
-logger = logging.getLogger('apprise')
+# Create ourselve a generic (singleton) logging reference
+logger = logging.getLogger(LOGGER_NAME)
+
+
+class LogCapture(object):
+ """
+ A class used to allow one to instantiate loggers that write to
+ memory for temporary purposes. e.g.:
+
+ 1. with LogCapture() as captured:
+ 2.
+ 3. # Send our notification(s)
+ 4. aobj.notify("hello world")
+ 5.
+ 6. # retrieve our logs produced by the above call via our
+ 7. # `captured` StringIO object we have access to within the `with`
+ 8. # block here:
+ 9. print(captured.getvalue())
+
+ """
+ def __init__(self, path=None, level=None, name=LOGGER_NAME, delete=True,
+ fmt='%(asctime)s - %(levelname)s - %(message)s'):
+ """
+ Instantiate a temporary log capture object
+
+ If a path is specified, then log content is sent to that file instead
+ of a StringIO object.
+
+ You can optionally specify a logging level such as logging.INFO if you
+ wish, otherwise by default the script uses whatever logging has been
+ set globally. If you set delete to `False` then when using log files,
+ they are not automatically cleaned up afterwards.
+
+ Optionally over-ride the fmt as well if you wish.
+
+ """
+ # Our memory buffer placeholder
+ self.__buffer_ptr = StringIO()
+
+ # Store our file path as it will determine whether or not we write to
+ # memory and a file
+ self.__path = path
+ self.__delete = delete
+
+ # Our logging level tracking
+ self.__level = level
+ self.__restore_level = None
+
+ # Acquire a pointer to our logger
+ self.__logger = logging.getLogger(name)
+
+ # Prepare our handler
+ self.__handler = logging.StreamHandler(self.__buffer_ptr) \
+ if not self.__path else logging.FileHandler(
+ self.__path, mode='a', encoding='utf-8')
+
+ # Use the specified level, otherwise take on the already
+ # effective level of our logger
+ self.__handler.setLevel(
+ self.__level if self.__level is not None
+ else self.__logger.getEffectiveLevel())
+
+ # Prepare our formatter
+ self.__handler.setFormatter(logging.Formatter(fmt))
+
+ def __enter__(self):
+ """
+ Allows logger manipulation within a 'with' block
+ """
+
+ if self.__level is not None:
+ # Temporary adjust our log level if required
+ self.__restore_level = self.__logger.getEffectiveLevel()
+ if self.__restore_level > self.__level:
+ # Bump our log level up for the duration of our `with`
+ self.__logger.setLevel(self.__level)
+
+ else:
+ # No restoration required
+ self.__restore_level = None
+
+ else:
+ # Do nothing but enforce that we have nothing to restore to
+ self.__restore_level = None
+
+ if self.__path:
+ # If a path has been identified, ensure we can write to the path
+ # and that the file exists
+ with open(self.__path, 'a'):
+ os.utime(self.__path, None)
+
+ # Update our buffer pointer
+ self.__buffer_ptr = open(self.__path, 'r')
+
+ # Add our handler
+ self.__logger.addHandler(self.__handler)
+
+ # return our memory pointer
+ return self.__buffer_ptr
+
+ def __exit__(self, exc_type, exc_value, tb):
+ """
+ removes the handler gracefully when the with block has completed
+ """
+
+ # Flush our content
+ self.__handler.flush()
+ self.__buffer_ptr.flush()
+
+ # Drop our handler
+ self.__logger.removeHandler(self.__handler)
+
+ if self.__restore_level is not None:
+ # Restore level
+ self.__logger.setLevel(self.__restore_level)
+
+ if self.__path:
+ # Close our file pointer
+ self.__buffer_ptr.close()
+ if self.__delete:
+ try:
+ # Always remove file afterwards
+ os.unlink(self.__path)
+
+ except OSError:
+ # It's okay if the file does not exist
+ pass
+
+ if exc_type is not None:
+ # pass exception on if one was generated
+ return False
+
+ return True
diff --git a/libs/apprise/plugins/NotifyAppriseAPI.py b/libs/apprise/plugins/NotifyAppriseAPI.py
new file mode 100644
index 000000000..b981f97a2
--- /dev/null
+++ b/libs/apprise/plugins/NotifyAppriseAPI.py
@@ -0,0 +1,382 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 Chris Caron
+# All rights reserved.
+#
+# This code is licensed under the MIT License.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files(the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions :
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import re
+import six
+import requests
+from json import dumps
+
+from .NotifyBase import NotifyBase
+from ..URLBase import PrivacyMode
+from ..common import NotifyType
+from ..utils import parse_list
+from ..utils import validate_regex
+from ..AppriseLocale import gettext_lazy as _
+
+
+class NotifyAppriseAPI(NotifyBase):
+ """
+ A wrapper for Apprise (Persistent) API Notifications
+ """
+
+ # The default descriptive name associated with the Notification
+ service_name = 'Apprise API'
+
+ # The services URL
+ service_url = 'https://github.com/caronc/apprise-api'
+
+ # The default protocol
+ protocol = 'apprise'
+
+ # The default secure protocol
+ secure_protocol = 'apprises'
+
+ # A URL that takes you to the setup/help of the specific protocol
+ setup_url = 'https://github.com/caronc/apprise/wiki/Notify_apprise_api'
+
+ # Depending on the number of transactions/notifications taking place, this
+ # could take a while. 30 seconds should be enough to perform the task
+ socket_connect_timeout = 30.0
+
+ # Disable throttle rate for Apprise API requests since they are normally
+ # local anyway
+ request_rate_per_sec = 0.0
+
+ # Define object templates
+ templates = (
+ '{schema}://{host}/{token}',
+ '{schema}://{host}:{port}/{token}',
+ '{schema}://{user}@{host}/{token}',
+ '{schema}://{user}@{host}:{port}/{token}',
+ '{schema}://{user}:{password}@{host}/{token}',
+ '{schema}://{user}:{password}@{host}:{port}/{token}',
+ )
+
+ # Define our tokens; these are the minimum tokens required required to
+ # be passed into this function (as arguments). The syntax appends any
+ # previously defined in the base package and builds onto them
+ template_tokens = dict(NotifyBase.template_tokens, **{
+ 'host': {
+ 'name': _('Hostname'),
+ 'type': 'string',
+ 'required': True,
+ },
+ 'port': {
+ 'name': _('Port'),
+ 'type': 'int',
+ 'min': 1,
+ 'max': 65535,
+ },
+ 'user': {
+ 'name': _('Username'),
+ 'type': 'string',
+ },
+ 'password': {
+ 'name': _('Password'),
+ 'type': 'string',
+ 'private': True,
+ },
+ 'token': {
+ 'name': _('Token'),
+ 'type': 'string',
+ 'required': True,
+ 'private': True,
+ 'regex': (r'^[A-Z0-9_-]{1,32}$', 'i'),
+ },
+ })
+
+ # Define our template arguments
+ template_args = dict(NotifyBase.template_args, **{
+ 'tags': {
+ 'name': _('Tags'),
+ 'type': 'string',
+ },
+ 'to': {
+ 'alias_of': 'token',
+ },
+ })
+
+ # Define any kwargs we're using
+ template_kwargs = {
+ 'headers': {
+ 'name': _('HTTP Header'),
+ 'prefix': '+',
+ },
+ }
+
+ def __init__(self, token=None, tags=None, headers=None, **kwargs):
+ """
+ Initialize Apprise API Object
+
+ headers can be a dictionary of key/value pairs that you want to
+ additionally include as part of the server headers to post with
+
+ """
+ super(NotifyAppriseAPI, self).__init__(**kwargs)
+
+ self.fullpath = kwargs.get('fullpath')
+ if not isinstance(self.fullpath, six.string_types):
+ self.fullpath = '/'
+
+ self.token = validate_regex(
+ token, *self.template_tokens['token']['regex'])
+ if not self.token:
+ msg = 'The Apprise API token specified ({}) is invalid.'\
+ .format(token)
+ self.logger.warning(msg)
+ raise TypeError(msg)
+
+ # Build list of tags
+ self.__tags = parse_list(tags)
+
+ self.headers = {}
+ if headers:
+ # Store our extra headers
+ self.headers.update(headers)
+
+ return
+
+ def url(self, privacy=False, *args, **kwargs):
+ """
+ Returns the URL built dynamically based on specified arguments.
+ """
+
+ # Our URL parameters
+ params = self.url_parameters(privacy=privacy, *args, **kwargs)
+
+ # Append our headers into our parameters
+ params.update({'+{}'.format(k): v for k, v in self.headers.items()})
+
+ if self.__tags:
+ params['tags'] = ','.join([x for x in self.__tags])
+
+ # Determine Authentication
+ auth = ''
+ if self.user and self.password:
+ auth = '{user}:{password}@'.format(
+ user=NotifyAppriseAPI.quote(self.user, safe=''),
+ password=self.pprint(
+ self.password, privacy, mode=PrivacyMode.Secret, safe=''),
+ )
+ elif self.user:
+ auth = '{user}@'.format(
+ user=NotifyAppriseAPI.quote(self.user, safe=''),
+ )
+
+ default_port = 443 if self.secure else 80
+
+ fullpath = self.fullpath.strip('/')
+ return '{schema}://{auth}{hostname}{port}{fullpath}{token}' \
+ '/?{params}'.format(
+ schema=self.secure_protocol
+ if self.secure else self.protocol,
+ auth=auth,
+ # never encode hostname since we're expecting it to be a
+ # valid one
+ hostname=self.host,
+ port='' if self.port is None or self.port == default_port
+ else ':{}'.format(self.port),
+ fullpath='/{}/'.format(NotifyAppriseAPI.quote(
+ fullpath, safe='/')) if fullpath else '/',
+ token=self.pprint(self.token, privacy, safe=''),
+ params=NotifyAppriseAPI.urlencode(params))
+
+ def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
+ """
+ Perform Apprise API Notification
+ """
+
+ headers = {}
+ # Apply any/all header over-rides defined
+ headers.update(self.headers)
+
+ # prepare Apprise API Object
+ payload = {
+ # Apprise API Payload
+ 'title': title,
+ 'body': body,
+ 'type': notify_type,
+ 'format': self.notify_format,
+ }
+
+ if self.__tags:
+ payload['tag'] = self.__tags
+
+ auth = None
+ if self.user:
+ auth = (self.user, self.password)
+
+ # Set our schema
+ schema = 'https' if self.secure else 'http'
+
+ url = '%s://%s' % (schema, self.host)
+ if isinstance(self.port, int):
+ url += ':%d' % self.port
+
+ fullpath = self.fullpath.strip('/')
+ url += '/{}/'.format(fullpath) if fullpath else '/'
+ url += 'notify/{}'.format(self.token)
+
+ # Some entries can not be over-ridden
+ headers.update({
+ 'User-Agent': self.app_id,
+ 'Content-Type': 'application/json',
+ # Pass our Source UUID4 Identifier
+ 'X-Apprise-ID': self.asset._uid,
+ # Pass our current recursion count to our upstream server
+ 'X-Apprise-Recursion-Count': str(self.asset._recursion + 1),
+ })
+
+ self.logger.debug('Apprise API POST URL: %s (cert_verify=%r)' % (
+ url, self.verify_certificate,
+ ))
+ self.logger.debug('Apprise API Payload: %s' % str(payload))
+
+ # Always call throttle before any remote server i/o is made
+ self.throttle()
+
+ try:
+ r = requests.post(
+ url,
+ data=dumps(payload),
+ headers=headers,
+ auth=auth,
+ verify=self.verify_certificate,
+ timeout=self.request_timeout,
+ )
+ if r.status_code != requests.codes.ok:
+ # We had a problem
+ status_str = \
+ NotifyAppriseAPI.http_response_code_lookup(r.status_code)
+
+ self.logger.warning(
+ 'Failed to send Apprise API notification: '
+ '{}{}error={}.'.format(
+ status_str,
+ ', ' if status_str else '',
+ r.status_code))
+
+ self.logger.debug('Response Details:\r\n{}'.format(r.content))
+
+ # Return; we're done
+ return False
+
+ else:
+ self.logger.info('Sent Apprise API notification.')
+
+ except requests.RequestException as e:
+ self.logger.warning(
+ 'A Connection error occurred sending Apprise API '
+ 'notification to %s.' % self.host)
+ self.logger.debug('Socket Exception: %s' % str(e))
+
+ # Return; we're done
+ return False
+
+ return True
+
+ @staticmethod
+ def parse_native_url(url):
+ """
+ Support http://hostname/notify/token and
+ http://hostname/path/notify/token
+ """
+
+ result = re.match(
+ r'^http(?Ps?)://(?P[A-Z0-9._-]+)'
+ r'(:(?P[0-9]+))?'
+ r'(?P/[^?]+?)?/notify/(?P[A-Z0-9_-]{1,32})/?'
+ r'(?P\?.+)?$', url, re.I)
+
+ if result:
+ return NotifyAppriseAPI.parse_url(
+ '{schema}://{hostname}{port}{path}/{token}/{params}'.format(
+ schema=NotifyAppriseAPI.secure_protocol
+ if result.group('secure') else NotifyAppriseAPI.protocol,
+ hostname=result.group('hostname'),
+ port='' if not result.group('port')
+ else ':{}'.format(result.group('port')),
+ path='' if not result.group('path')
+ else result.group('path'),
+ token=result.group('token'),
+ params='' if not result.group('params')
+ else '?{}'.format(result.group('params'))))
+
+ return None
+
+ @staticmethod
+ def parse_url(url):
+ """
+ Parses the URL and returns enough arguments that can allow
+ us to re-instantiate this object.
+
+ """
+ results = NotifyBase.parse_url(url)
+ if not results:
+ # We're done early as we couldn't load the results
+ return results
+
+ # Add our headers that the user can potentially over-ride if they wish
+ # to to our returned result set
+ results['headers'] = results['qsd+']
+ if results['qsd-']:
+ results['headers'].update(results['qsd-'])
+ NotifyBase.logger.deprecate(
+ "minus (-) based Apprise API header tokens are being "
+ " removed; use the plus (+) symbol instead.")
+
+ # Tidy our header entries by unquoting them
+ results['headers'] = \
+ {NotifyAppriseAPI.unquote(x): NotifyAppriseAPI.unquote(y)
+ for x, y in results['headers'].items()}
+
+ # Support the passing of tags in the URL
+ if 'tags' in results['qsd'] and len(results['qsd']['tags']):
+ results['tags'] = \
+ NotifyAppriseAPI.parse_list(results['qsd']['tags'])
+
+ # Support the 'to' & 'token' variable so that we can support rooms
+ # this way too.
+ if 'token' in results['qsd'] and len(results['qsd']['token']):
+ results['token'] = \
+ NotifyAppriseAPI.unquote(results['qsd']['token'])
+
+ elif 'to' in results['qsd'] and len(results['qsd']['to']):
+ results['token'] = NotifyAppriseAPI.unquote(results['qsd']['to'])
+
+ else:
+ # Start with a list of path entries to work with
+ entries = NotifyAppriseAPI.split_path(results['fullpath'])
+ if entries:
+ # use our last entry found
+ results['token'] = entries[-1]
+
+ # pop our last entry off
+ entries = entries[:-1]
+
+ # re-assemble our full path
+ results['fullpath'] = '/'.join(entries)
+
+ return results
diff --git a/libs/apprise/plugins/NotifyBase.py b/libs/apprise/plugins/NotifyBase.py
index 3a0538bcc..82c025506 100644
--- a/libs/apprise/plugins/NotifyBase.py
+++ b/libs/apprise/plugins/NotifyBase.py
@@ -52,6 +52,54 @@ class NotifyBase(BASE_OBJECT):
This is the base class for all notification services
"""
+ # An internal flag used to test the state of the plugin. If set to
+ # False, then the plugin is not used. Plugins can disable themselves
+ # due to enviroment issues (such as missing libraries, or platform
+ # dependencies that are not present). By default all plugins are
+ # enabled.
+ enabled = True
+
+ # Some plugins may require additional packages above what is provided
+ # already by Apprise.
+ #
+ # Use this section to relay this information to the users of the script to
+ # help guide them with what they need to know if they plan on using your
+ # plugin. The below configuration should otherwise accomodate all normal
+ # situations and will not requrie any updating:
+ requirements = {
+ # Use the description to provide a human interpretable description of
+ # what is required to make the plugin work. This is only nessisary
+ # if there are package dependencies. Setting this to default will
+ # cause a general response to be returned. Only set this if you plan
+ # on over-riding the default. Always consider language support here.
+ # So before providing a value do the following in your code base:
+ #
+ # from apprise.AppriseLocale import gettext_lazy as _
+ #
+ # 'details': _('My detailed requirements')
+ 'details': None,
+
+ # Define any required packages needed for the plugin to run. This is
+ # an array of strings that simply look like lines residing in a
+ # `requirements.txt` file...
+ #
+ # As an example, an entry may look like:
+ # 'packages_required': [
+ # 'cryptography < 3.4`,
+ # ]
+ 'packages_required': [],
+
+ # Recommended packages identify packages that are not required to make
+ # your plugin work, but would improve it's use or grant it access to
+ # full functionality (that might otherwise be limited).
+
+ # Similar to `packages_required`, you would identify each entry in
+ # the array as you would in a `requirements.txt` file.
+ #
+ # - Do not re-provide entries already in the `packages_required`
+ 'packages_recommended': [],
+ }
+
# The services URL
service_url = None
@@ -153,7 +201,8 @@ class NotifyBase(BASE_OBJECT):
# Provide override
self.overflow_mode = overflow
- def image_url(self, notify_type, logo=False, extension=None):
+ def image_url(self, notify_type, logo=False, extension=None,
+ image_size=None):
"""
Returns Image URL if possible
"""
@@ -166,7 +215,7 @@ class NotifyBase(BASE_OBJECT):
return self.asset.image_url(
notify_type=notify_type,
- image_size=self.image_size,
+ image_size=self.image_size if image_size is None else image_size,
logo=logo,
extension=extension,
)
@@ -222,6 +271,13 @@ class NotifyBase(BASE_OBJECT):
"""
+ if not self.enabled:
+ # Deny notifications issued to services that are disabled
+ self.logger.warning(
+ "{} is currently disabled on this system.".format(
+ self.service_name))
+ return False
+
# Prepare attachments if required
if attach is not None and not isinstance(attach, AppriseAttachment):
try:
diff --git a/libs/apprise/plugins/NotifyBase.pyi b/libs/apprise/plugins/NotifyBase.pyi
new file mode 100644
index 000000000..9cf3e404c
--- /dev/null
+++ b/libs/apprise/plugins/NotifyBase.pyi
@@ -0,0 +1 @@
+class NotifyBase: ...
\ No newline at end of file
diff --git a/libs/apprise/plugins/NotifyClickSend.py b/libs/apprise/plugins/NotifyClickSend.py
index a7d89c18b..9054c6f01 100644
--- a/libs/apprise/plugins/NotifyClickSend.py
+++ b/libs/apprise/plugins/NotifyClickSend.py
@@ -36,7 +36,6 @@
# The API reference used to build this plugin was documented here:
# https://developers.clicksend.com/docs/rest/v3/
#
-import re
import requests
from json import dumps
from base64 import b64encode
@@ -44,7 +43,8 @@ from base64 import b64encode
from .NotifyBase import NotifyBase
from ..URLBase import PrivacyMode
from ..common import NotifyType
-from ..utils import parse_list
+from ..utils import is_phone_no
+from ..utils import parse_phone_no
from ..utils import parse_bool
from ..AppriseLocale import gettext_lazy as _
@@ -53,12 +53,6 @@ CLICKSEND_HTTP_ERROR_MAP = {
401: 'Unauthorized - Invalid Token.',
}
-# Some Phone Number Detection
-IS_PHONE_NO = re.compile(r'^\+?(?P[0-9\s)(+-]+)\s*$')
-
-# Used to break path apart into list of channels
-TARGET_LIST_DELIM = re.compile(r'[ \t\r\n,#\\/]+')
-
class NotifyClickSend(NotifyBase):
"""
@@ -151,26 +145,18 @@ class NotifyClickSend(NotifyBase):
self.logger.warning(msg)
raise TypeError(msg)
- for target in parse_list(targets):
+ for target in parse_phone_no(targets):
# Validate targets and drop bad ones:
- result = IS_PHONE_NO.match(target)
- if result:
- # Further check our phone # for it's digit count
- result = ''.join(re.findall(r'\d+', result.group('phone')))
- if len(result) < 11 or len(result) > 14:
- self.logger.warning(
- 'Dropped invalid phone # '
- '({}) specified.'.format(target),
- )
- continue
-
- # store valid phone number
- self.targets.append(result)
+ result = is_phone_no(target)
+ if not result:
+ self.logger.warning(
+ 'Dropped invalid phone # '
+ '({}) specified.'.format(target),
+ )
continue
- self.logger.warning(
- 'Dropped invalid phone # '
- '({}) specified.'.format(target))
+ # store valid phone number
+ self.targets.append(result['full'])
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
"""
@@ -321,8 +307,7 @@ class NotifyClickSend(NotifyBase):
# Support the 'to' variable so that we can support rooms this way too
# The 'to' makes it easier to use yaml configuration
if 'to' in results['qsd'] and len(results['qsd']['to']):
- results['targets'] += [x for x in filter(
- bool, TARGET_LIST_DELIM.split(
- NotifyClickSend.unquote(results['qsd']['to'])))]
+ results['targets'] += \
+ NotifyClickSend.parse_phone_no(results['qsd']['to'])
return results
diff --git a/libs/apprise/plugins/NotifyD7Networks.py b/libs/apprise/plugins/NotifyD7Networks.py
index f04082c68..728f119ab 100644
--- a/libs/apprise/plugins/NotifyD7Networks.py
+++ b/libs/apprise/plugins/NotifyD7Networks.py
@@ -30,7 +30,6 @@
# (both user and password) from the API Details section from within your
# account profile area: https://d7networks.com/accounts/profile/
-import re
import six
import requests
import base64
@@ -40,7 +39,8 @@ from json import loads
from .NotifyBase import NotifyBase
from ..URLBase import PrivacyMode
from ..common import NotifyType
-from ..utils import parse_list
+from ..utils import is_phone_no
+from ..utils import parse_phone_no
from ..utils import parse_bool
from ..AppriseLocale import gettext_lazy as _
@@ -52,9 +52,6 @@ D7NETWORKS_HTTP_ERROR_MAP = {
500: 'A Serverside Error Occured Handling the Request.',
}
-# Some Phone Number Detection
-IS_PHONE_NO = re.compile(r'^\+?(?P[0-9\s)(+-]+)\s*$')
-
# Priorities
class D7SMSPriority(object):
@@ -197,36 +194,26 @@ class NotifyD7Networks(NotifyBase):
self.source = None \
if not isinstance(source, six.string_types) else source.strip()
- # Parse our targets
- self.targets = list()
-
- for target in parse_list(targets):
- # Validate targets and drop bad ones:
- result = IS_PHONE_NO.match(target)
- if result:
- # Further check our phone # for it's digit count
- # if it's less than 10, then we can assume it's
- # a poorly specified phone no and spit a warning
- result = ''.join(re.findall(r'\d+', result.group('phone')))
- if len(result) < 11 or len(result) > 14:
- self.logger.warning(
- 'Dropped invalid phone # '
- '({}) specified.'.format(target),
- )
- continue
-
- # store valid phone number
- self.targets.append(result)
- continue
-
- self.logger.warning(
- 'Dropped invalid phone # ({}) specified.'.format(target))
-
- if len(self.targets) == 0:
- msg = 'There are no valid targets identified to notify.'
+ if not (self.user and self.password):
+ msg = 'A D7 Networks user/pass was not provided.'
self.logger.warning(msg)
raise TypeError(msg)
+ # Parse our targets
+ self.targets = list()
+ for target in parse_phone_no(targets):
+ # Validate targets and drop bad ones:
+ result = result = is_phone_no(target)
+ if not result:
+ self.logger.warning(
+ 'Dropped invalid phone # '
+ '({}) specified.'.format(target),
+ )
+ continue
+
+ # store valid phone number
+ self.targets.append(result['full'])
+
return
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
@@ -235,6 +222,11 @@ class NotifyD7Networks(NotifyBase):
redirects to the appropriate handling
"""
+ if len(self.targets) == 0:
+ # There were no services to notify
+ self.logger.warning('There were no D7 Networks targets to notify.')
+ return False
+
# error tracking (used for function return)
has_error = False
@@ -479,6 +471,6 @@ class NotifyD7Networks(NotifyBase):
# The 'to' makes it easier to use yaml configuration
if 'to' in results['qsd'] and len(results['qsd']['to']):
results['targets'] += \
- NotifyD7Networks.parse_list(results['qsd']['to'])
+ NotifyD7Networks.parse_phone_no(results['qsd']['to'])
return results
diff --git a/libs/apprise/plugins/NotifyDBus.py b/libs/apprise/plugins/NotifyDBus.py
index ca501bf9e..145e1c05c 100644
--- a/libs/apprise/plugins/NotifyDBus.py
+++ b/libs/apprise/plugins/NotifyDBus.py
@@ -38,10 +38,6 @@ NOTIFY_DBUS_SUPPORT_ENABLED = False
# Image support is dependant on the GdkPixbuf library being available
NOTIFY_DBUS_IMAGE_SUPPORT = False
-# The following are required to hook into the notifications:
-NOTIFY_DBUS_INTERFACE = 'org.freedesktop.Notifications'
-NOTIFY_DBUS_SETTING_LOCATION = '/org/freedesktop/Notifications'
-
# Initialize our mainloops
LOOP_GLIB = None
LOOP_QT = None
@@ -132,8 +128,19 @@ class NotifyDBus(NotifyBase):
A wrapper for local DBus/Qt Notifications
"""
+ # Set our global enabled flag
+ enabled = NOTIFY_DBUS_SUPPORT_ENABLED
+
+ requirements = {
+ # Define our required packaging in order to work
+ 'details': _('libdbus-1.so.x must be installed.')
+ }
+
# The default descriptive name associated with the Notification
- service_name = 'DBus Notification'
+ service_name = _('DBus Notification')
+
+ # The services URL
+ service_url = 'http://www.freedesktop.org/Software/dbus/'
# The default protocols
# Python 3 keys() does not return a list object, it's it's own dict_keys()
@@ -158,14 +165,9 @@ class NotifyDBus(NotifyBase):
# content to display
body_max_line_count = 10
- # This entry is a bit hacky, but it allows us to unit-test this library
- # in an environment that simply doesn't have the gnome packages
- # available to us. It also allows us to handle situations where the
- # packages actually are present but we need to test that they aren't.
- # If anyone is seeing this had knows a better way of testing this
- # outside of what is defined in test/test_glib_plugin.py, please
- # let me know! :)
- _enabled = NOTIFY_DBUS_SUPPORT_ENABLED
+ # The following are required to hook into the notifications:
+ dbus_interface = 'org.freedesktop.Notifications'
+ dbus_setting_location = '/org/freedesktop/Notifications'
# Define object templates
templates = (
@@ -241,12 +243,6 @@ class NotifyDBus(NotifyBase):
"""
Perform DBus Notification
"""
-
- if not self._enabled or MAINLOOP_MAP[self.schema] is None:
- self.logger.warning(
- "{} notifications could not be loaded.".format(self.schema))
- return False
-
# Acquire our session
try:
session = SessionBus(mainloop=MAINLOOP_MAP[self.schema])
@@ -265,14 +261,14 @@ class NotifyDBus(NotifyBase):
# acquire our dbus object
dbus_obj = session.get_object(
- NOTIFY_DBUS_INTERFACE,
- NOTIFY_DBUS_SETTING_LOCATION,
+ self.dbus_interface,
+ self.dbus_setting_location,
)
# Acquire our dbus interface
dbus_iface = Interface(
dbus_obj,
- dbus_interface=NOTIFY_DBUS_INTERFACE,
+ dbus_interface=self.dbus_interface,
)
# image path
diff --git a/libs/apprise/plugins/NotifyDingTalk.py b/libs/apprise/plugins/NotifyDingTalk.py
new file mode 100644
index 000000000..68c069479
--- /dev/null
+++ b/libs/apprise/plugins/NotifyDingTalk.py
@@ -0,0 +1,343 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2020 Chris Caron
+# All rights reserved.
+#
+# This code is licensed under the MIT License.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files(the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions :
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import re
+import time
+import hmac
+import hashlib
+import base64
+import requests
+from json import dumps
+
+from .NotifyBase import NotifyBase
+from ..URLBase import PrivacyMode
+from ..common import NotifyFormat
+from ..common import NotifyType
+from ..utils import parse_list
+from ..utils import validate_regex
+from ..AppriseLocale import gettext_lazy as _
+
+# Register at https://dingtalk.com
+# - Download their PC based software as it is the only way you can create
+# a custom robot. You can create a custom robot per group. You will
+# be provided an access_token that Apprise will need.
+
+# Syntax:
+# dingtalk://{access_token}/
+# dingtalk://{access_token}/{optional_phone_no}
+# dingtalk://{access_token}/{phone_no_1}/{phone_no_2}/{phone_no_N/
+
+# Some Phone Number Detection
+IS_PHONE_NO = re.compile(r'^\+?(?P[0-9\s)(+-]+)\s*$')
+
+
+class NotifyDingTalk(NotifyBase):
+ """
+ A wrapper for DingTalk Notifications
+ """
+
+ # The default descriptive name associated with the Notification
+ service_name = 'DingTalk'
+
+ # The services URL
+ service_url = 'https://www.dingtalk.com/'
+
+ # All notification requests are secure
+ secure_protocol = 'dingtalk'
+
+ # A URL that takes you to the setup/help of the specific protocol
+ setup_url = 'https://github.com/caronc/apprise/wiki/Notify_dingtalk'
+
+ # DingTalk API
+ notify_url = 'https://oapi.dingtalk.com/robot/send?access_token={token}'
+
+ # Do not set title_maxlen as it is set in a property value below
+ # since the length varies depending if we are doing a markdown
+ # based message or a text based one.
+ # title_maxlen = see below @propery defined
+
+ # Define object templates
+ templates = (
+ '{schema}://{token}/',
+ '{schema}://{token}/{targets}/',
+ '{schema}://{secret}@{token}/',
+ '{schema}://{secret}@{token}/{targets}/',
+ )
+
+ # Define our template tokens
+ template_tokens = dict(NotifyBase.template_tokens, **{
+ 'token': {
+ 'name': _('Token'),
+ 'type': 'string',
+ 'private': True,
+ 'required': True,
+ 'regex': (r'^[a-z0-9]+$', 'i'),
+ },
+ 'secret': {
+ 'name': _('Token'),
+ 'type': 'string',
+ 'private': True,
+ 'regex': (r'^[a-z0-9]+$', 'i'),
+ },
+ 'targets': {
+ 'name': _('Target Phone No'),
+ 'type': 'list:string',
+ },
+ })
+
+ # Define our template arguments
+ template_args = dict(NotifyBase.template_args, **{
+ 'to': {
+ 'alias_of': 'targets',
+ },
+ 'token': {
+ 'alias_of': 'token',
+ },
+ 'secret': {
+ 'alias_of': 'secret',
+ },
+ })
+
+ def __init__(self, token, targets=None, secret=None, **kwargs):
+ """
+ Initialize DingTalk Object
+ """
+ super(NotifyDingTalk, self).__init__(**kwargs)
+
+ # Secret Key (associated with project)
+ self.token = validate_regex(
+ token, *self.template_tokens['token']['regex'])
+ if not self.token:
+ msg = 'An invalid DingTalk API Token ' \
+ '({}) was specified.'.format(token)
+ self.logger.warning(msg)
+ raise TypeError(msg)
+
+ self.secret = None
+ if secret:
+ self.secret = validate_regex(
+ secret, *self.template_tokens['secret']['regex'])
+ if not self.secret:
+ msg = 'An invalid DingTalk Secret ' \
+ '({}) was specified.'.format(token)
+ self.logger.warning(msg)
+ raise TypeError(msg)
+
+ # Parse our targets
+ self.targets = list()
+
+ for target in parse_list(targets):
+ # Validate targets and drop bad ones:
+ result = IS_PHONE_NO.match(target)
+ if result:
+ # Further check our phone # for it's digit count
+ result = ''.join(re.findall(r'\d+', result.group('phone')))
+ if len(result) < 11 or len(result) > 14:
+ self.logger.warning(
+ 'Dropped invalid phone # '
+ '({}) specified.'.format(target),
+ )
+ continue
+
+ # store valid phone number
+ self.targets.append(result)
+ continue
+
+ self.logger.warning(
+ 'Dropped invalid phone # '
+ '({}) specified.'.format(target),
+ )
+
+ return
+
+ def get_signature(self):
+ """
+ Calculates time-based signature so that we can send arbitrary messages.
+ """
+ timestamp = str(round(time.time() * 1000))
+ secret_enc = self.secret.encode('utf-8')
+ str_to_sign_enc = \
+ "{}\n{}".format(timestamp, self.secret).encode('utf-8')
+ hmac_code = hmac.new(
+ secret_enc, str_to_sign_enc, digestmod=hashlib.sha256).digest()
+ signature = NotifyDingTalk.quote(base64.b64encode(hmac_code), safe='')
+ return timestamp, signature
+
+ def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
+ """
+ Perform DingTalk Notification
+ """
+
+ payload = {
+ 'msgtype': 'text',
+ 'at': {
+ 'atMobiles': self.targets,
+ 'isAtAll': False,
+ }
+ }
+
+ if self.notify_format == NotifyFormat.MARKDOWN:
+ payload['markdown'] = {
+ 'title': title,
+ 'text': body,
+ }
+
+ else:
+ payload['text'] = {
+ 'content': body,
+ }
+
+ # Our Notification URL
+ notify_url = self.notify_url.format(token=self.token)
+
+ params = None
+ if self.secret:
+ timestamp, signature = self.get_signature()
+ params = {
+ 'timestamp': timestamp,
+ 'sign': signature,
+ }
+
+ # Prepare our headers
+ headers = {
+ 'User-Agent': self.app_id,
+ 'Content-Type': 'application/json'
+ }
+
+ # Some Debug Logging
+ self.logger.debug('DingTalk URL: {} (cert_verify={})'.format(
+ notify_url, self.verify_certificate))
+ self.logger.debug('DingTalk Payload: {}' .format(payload))
+
+ # Always call throttle before any remote server i/o is made
+ self.throttle()
+
+ try:
+ r = requests.post(
+ notify_url,
+ data=dumps(payload),
+ headers=headers,
+ params=params,
+ verify=self.verify_certificate,
+ )
+
+ if r.status_code != requests.codes.ok:
+ # We had a problem
+ status_str = \
+ NotifyDingTalk.http_response_code_lookup(
+ r.status_code)
+
+ self.logger.warning(
+ 'Failed to send DingTalk notification: '
+ '{}{}error={}.'.format(
+ status_str,
+ ', ' if status_str else '',
+ r.status_code))
+
+ self.logger.debug(
+ 'Response Details:\r\n{}'.format(r.content))
+ return False
+
+ else:
+ self.logger.info('Sent DingTalk notification.')
+
+ except requests.RequestException as e:
+ self.logger.warning(
+ 'A Connection error occured sending DingTalk '
+ 'notification.'
+ )
+ self.logger.debug('Socket Exception: %s' % str(e))
+ return False
+
+ return True
+
+ @property
+ def title_maxlen(self):
+ """
+ The title isn't used when not in markdown mode.
+ """
+ return NotifyBase.title_maxlen \
+ if self.notify_format == NotifyFormat.MARKDOWN else 0
+
+ def url(self, privacy=False, *args, **kwargs):
+ """
+ Returns the URL built dynamically based on specified arguments.
+ """
+
+ # Define any arguments set
+ args = {
+ 'format': self.notify_format,
+ 'overflow': self.overflow_mode,
+ 'verify': 'yes' if self.verify_certificate else 'no',
+ }
+
+ return '{schema}://{secret}{token}/{targets}/?{args}'.format(
+ schema=self.secure_protocol,
+ secret='' if not self.secret else '{}@'.format(self.pprint(
+ self.secret, privacy, mode=PrivacyMode.Secret, safe='')),
+ token=self.pprint(self.token, privacy, safe=''),
+ targets='/'.join(
+ [NotifyDingTalk.quote(x, safe='') for x in self.targets]),
+ args=NotifyDingTalk.urlencode(args))
+
+ @staticmethod
+ def parse_url(url):
+ """
+ Parses the URL and returns enough arguments that can allow
+ us to substantiate this object.
+
+ """
+ results = NotifyBase.parse_url(url, verify_host=False)
+ if not results:
+ # We're done early as we couldn't load the results
+ return results
+
+ results['token'] = NotifyDingTalk.unquote(results['host'])
+
+ # if a user has been defined, use it's value as the secret
+ if results.get('user'):
+ results['secret'] = results.get('user')
+
+ # Get our entries; split_path() looks after unquoting content for us
+ # by default
+ results['targets'] = NotifyDingTalk.split_path(results['fullpath'])
+
+ # Support the use of the `token` keyword argument
+ if 'token' in results['qsd'] and len(results['qsd']['token']):
+ results['token'] = \
+ NotifyDingTalk.unquote(results['qsd']['token'])
+
+ # Support the use of the `secret` keyword argument
+ if 'secret' in results['qsd'] and len(results['qsd']['secret']):
+ results['secret'] = \
+ NotifyDingTalk.unquote(results['qsd']['secret'])
+
+ # Support the 'to' variable so that we can support targets this way too
+ # The 'to' makes it easier to use yaml configuration
+ if 'to' in results['qsd'] and len(results['qsd']['to']):
+ results['targets'] += \
+ NotifyDingTalk.parse_list(results['qsd']['to'])
+
+ return results
diff --git a/libs/apprise/plugins/NotifyDiscord.py b/libs/apprise/plugins/NotifyDiscord.py
index 8a8b21f44..a4e7df6d4 100644
--- a/libs/apprise/plugins/NotifyDiscord.py
+++ b/libs/apprise/plugins/NotifyDiscord.py
@@ -80,6 +80,11 @@ class NotifyDiscord(NotifyBase):
# The maximum allowable characters allowed in the body per message
body_maxlen = 2000
+ # Discord has a limit of the number of fields you can include in an
+ # embeds message. This value allows the discord message to safely
+ # break into multiple messages to handle these cases.
+ discord_max_fields = 10
+
# Define object templates
templates = (
'{schema}://{webhook_id}/{webhook_token}',
@@ -133,6 +138,11 @@ class NotifyDiscord(NotifyBase):
'type': 'bool',
'default': True,
},
+ 'fields': {
+ 'name': _('Use Fields'),
+ 'type': 'bool',
+ 'default': True,
+ },
'image': {
'name': _('Include Image'),
'type': 'bool',
@@ -143,7 +153,7 @@ class NotifyDiscord(NotifyBase):
def __init__(self, webhook_id, webhook_token, tts=False, avatar=True,
footer=False, footer_logo=True, include_image=False,
- avatar_url=None, **kwargs):
+ fields=True, avatar_url=None, **kwargs):
"""
Initialize Discord Object
@@ -181,6 +191,9 @@ class NotifyDiscord(NotifyBase):
# Place a thumbnail image inline with the message body
self.include_image = include_image
+ # Use Fields
+ self.fields = fields
+
# Avatar URL
# This allows a user to provide an over-ride to the otherwise
# dynamically generated avatar url images
@@ -206,32 +219,23 @@ class NotifyDiscord(NotifyBase):
# Acquire image_url
image_url = self.image_url(notify_type)
+ # our fields variable
+ fields = []
+
if self.notify_format == NotifyFormat.MARKDOWN:
# Use embeds for payload
payload['embeds'] = [{
- 'provider': {
+ 'author': {
'name': self.app_id,
'url': self.app_url,
},
'title': title,
- 'type': 'rich',
'description': body,
# Our color associated with our notification
'color': self.color(notify_type, int),
}]
- # Break titles out so that we can sort them in embeds
- fields = self.extract_markdown_sections(body)
-
- if len(fields) > 0:
- # Apply our additional parsing for a better presentation
-
- # Swap first entry for description
- payload['embeds'][0]['description'] = \
- fields[0].get('name') + fields[0].get('value')
- payload['embeds'][0]['fields'] = fields[1:]
-
if self.footer:
# Acquire logo URL
logo_url = self.image_url(notify_type, logo=True)
@@ -251,6 +255,20 @@ class NotifyDiscord(NotifyBase):
'width': 256,
}
+ if self.fields:
+ # Break titles out so that we can sort them in embeds
+ description, fields = self.extract_markdown_sections(body)
+
+ # Swap first entry for description
+ payload['embeds'][0]['description'] = description
+ if fields:
+ # Apply our additional parsing for a better presentation
+ payload['embeds'][0]['fields'] = \
+ fields[:self.discord_max_fields]
+
+ # Remove entry from head of fields
+ fields = fields[self.discord_max_fields:]
+
else:
# not markdown
payload['content'] = \
@@ -268,6 +286,16 @@ class NotifyDiscord(NotifyBase):
# We failed to post our message
return False
+ # Process any remaining fields IF set
+ if fields:
+ payload['embeds'][0]['description'] = ''
+ for i in range(0, len(fields), self.discord_max_fields):
+ payload['embeds'][0]['fields'] = \
+ fields[i:i + self.discord_max_fields]
+ if not self._send(payload):
+ # We failed to post our message
+ return False
+
if attach:
# Update our payload; the idea is to preserve it's other detected
# and assigned values for re-use here too
@@ -413,8 +441,12 @@ class NotifyDiscord(NotifyBase):
'footer': 'yes' if self.footer else 'no',
'footer_logo': 'yes' if self.footer_logo else 'no',
'image': 'yes' if self.include_image else 'no',
+ 'fields': 'yes' if self.fields else 'no',
}
+ if self.avatar_url:
+ params['avatar_url'] = self.avatar_url
+
# Extend our parameters
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
@@ -459,6 +491,11 @@ class NotifyDiscord(NotifyBase):
# Text To Speech
results['tts'] = parse_bool(results['qsd'].get('tts', False))
+ # Use sections
+ # effectively detect multiple fields and break them off
+ # into sections
+ results['fields'] = parse_bool(results['qsd'].get('fields', True))
+
# Use Footer
results['footer'] = parse_bool(results['qsd'].get('footer', False))
@@ -513,6 +550,18 @@ class NotifyDiscord(NotifyBase):
fields that get passed as an embed entry to Discord.
"""
+ # Search for any header information found without it's own section
+ # identifier
+ match = re.match(
+ r'^\s*(?P[^\s#]+.*?)(?=\s*$|[\r\n]+\s*#)',
+ markdown, flags=re.S)
+
+ description = match.group('desc').strip() if match else ''
+ if description:
+ # Strip description from our string since it has been handled
+ # now.
+ markdown = re.sub(description, '', markdown, count=1)
+
regex = re.compile(
r'\s*#[# \t\v]*(?P[^\n]+)(\n|\s*$)'
r'\s*((?P[^#].+?)(?=\s*$|[\r\n]+\s*#))?', flags=re.S)
@@ -523,9 +572,11 @@ class NotifyDiscord(NotifyBase):
d = el.groupdict()
fields.append({
- 'name': d.get('name', '').strip('# \r\n\t\v'),
- 'value': '```md\n' +
- (d.get('value').strip() if d.get('value') else '') + '\n```'
+ 'name': d.get('name', '').strip('#`* \r\n\t\v'),
+ 'value': '```{}\n{}```'.format(
+ 'md' if d.get('value') else '',
+ d.get('value').strip() + '\n' if d.get('value') else '',
+ ),
})
- return fields
+ return description, fields
diff --git a/libs/apprise/plugins/NotifyEmail.py b/libs/apprise/plugins/NotifyEmail.py
index 604fc5b5c..7bd894387 100644
--- a/libs/apprise/plugins/NotifyEmail.py
+++ b/libs/apprise/plugins/NotifyEmail.py
@@ -106,6 +106,21 @@ EMAIL_TEMPLATES = (
},
),
+ # Yandex
+ (
+ 'Yandex',
+ re.compile(
+ r'^((?P
e")
diff --git a/libs/html5lib/tests/test_sanitizer.py b/libs/html5lib/tests/test_sanitizer.py
index 45046d572..f3faeb805 100644
--- a/libs/html5lib/tests/test_sanitizer.py
+++ b/libs/html5lib/tests/test_sanitizer.py
@@ -1,31 +1,22 @@
from __future__ import absolute_import, division, unicode_literals
+import pytest
+
from html5lib import constants, parseFragment, serialize
from html5lib.filters import sanitizer
-def runSanitizerTest(_, expected, input):
- parsed = parseFragment(expected)
- expected = serialize(parsed,
- omit_optional_tags=False,
- use_trailing_solidus=True,
- space_before_trailing_solidus=False,
- quote_attr_values="always",
- quote_char='"',
- alphabetical_attributes=True)
- assert expected == sanitize_html(input)
-
-
def sanitize_html(stream):
parsed = parseFragment(stream)
- serialized = serialize(parsed,
- sanitize=True,
- omit_optional_tags=False,
- use_trailing_solidus=True,
- space_before_trailing_solidus=False,
- quote_attr_values="always",
- quote_char='"',
- alphabetical_attributes=True)
+ with pytest.deprecated_call():
+ serialized = serialize(parsed,
+ sanitize=True,
+ omit_optional_tags=False,
+ use_trailing_solidus=True,
+ space_before_trailing_solidus=False,
+ quote_attr_values="always",
+ quote_char='"',
+ alphabetical_attributes=True)
return serialized
@@ -59,7 +50,7 @@ def test_data_uri_disallowed_type():
assert expected == sanitized
-def test_sanitizer():
+def param_sanitizer():
for ns, tag_name in sanitizer.allowed_elements:
if ns != constants.namespaces["html"]:
continue
@@ -67,19 +58,19 @@ def test_sanitizer():
'tfoot', 'th', 'thead', 'tr', 'select']:
continue # TODO
if tag_name == 'image':
- yield (runSanitizerTest, "test_should_allow_%s_tag" % tag_name,
+ yield ("test_should_allow_%s_tag" % tag_name,
"foo <bad>bar</bad> baz",
"<%s title='1'>foo bar baz%s>" % (tag_name, tag_name))
elif tag_name == 'br':
- yield (runSanitizerTest, "test_should_allow_%s_tag" % tag_name,
+ yield ("test_should_allow_%s_tag" % tag_name,
"
foo <bad>bar</bad> baz
",
"<%s title='1'>foo bar baz%s>" % (tag_name, tag_name))
elif tag_name in constants.voidElements:
- yield (runSanitizerTest, "test_should_allow_%s_tag" % tag_name,
+ yield ("test_should_allow_%s_tag" % tag_name,
"<%s title=\"1\"/>foo <bad>bar</bad> baz" % tag_name,
"<%s title='1'>foo bar baz%s>" % (tag_name, tag_name))
else:
- yield (runSanitizerTest, "test_should_allow_%s_tag" % tag_name,
+ yield ("test_should_allow_%s_tag" % tag_name,
"<%s title=\"1\">foo <bad>bar</bad> baz%s>" % (tag_name, tag_name),
"<%s title='1'>foo bar baz%s>" % (tag_name, tag_name))
@@ -93,7 +84,7 @@ def test_sanitizer():
attribute_value = 'foo'
if attribute_name in sanitizer.attr_val_is_uri:
attribute_value = '%s://sub.domain.tld/path/object.ext' % sanitizer.allowed_protocols[0]
- yield (runSanitizerTest, "test_should_allow_%s_attribute" % attribute_name,
+ yield ("test_should_allow_%s_attribute" % attribute_name,
"foo <bad>bar</bad> baz
" % (attribute_name, attribute_value),
"foo bar baz
" % (attribute_name, attribute_value))
@@ -101,7 +92,7 @@ def test_sanitizer():
rest_of_uri = '//sub.domain.tld/path/object.ext'
if protocol == 'data':
rest_of_uri = 'image/png;base64,aGVsbG8gd29ybGQ='
- yield (runSanitizerTest, "test_should_allow_uppercase_%s_uris" % protocol,
+ yield ("test_should_allow_uppercase_%s_uris" % protocol,
"foo" % (protocol, rest_of_uri),
"""foo""" % (protocol, rest_of_uri))
@@ -110,11 +101,26 @@ def test_sanitizer():
if protocol == 'data':
rest_of_uri = 'image/png;base64,aGVsbG8gd29ybGQ='
protocol = protocol.upper()
- yield (runSanitizerTest, "test_should_allow_uppercase_%s_uris" % protocol,
+ yield ("test_should_allow_uppercase_%s_uris" % protocol,
"foo" % (protocol, rest_of_uri),
"""foo""" % (protocol, rest_of_uri))
+@pytest.mark.parametrize("expected, input",
+ (pytest.param(expected, input, id=id)
+ for id, expected, input in param_sanitizer()))
+def test_sanitizer(expected, input):
+ parsed = parseFragment(expected)
+ expected = serialize(parsed,
+ omit_optional_tags=False,
+ use_trailing_solidus=True,
+ space_before_trailing_solidus=False,
+ quote_attr_values="always",
+ quote_char='"',
+ alphabetical_attributes=True)
+ assert expected == sanitize_html(input)
+
+
def test_lowercase_color_codes_in_style():
sanitized = sanitize_html("")
expected = ''
diff --git a/libs/html5lib/tests/test_serializer.py b/libs/html5lib/tests/test_serializer.py
index 9333286ef..bce624590 100644
--- a/libs/html5lib/tests/test_serializer.py
+++ b/libs/html5lib/tests/test_serializer.py
@@ -80,7 +80,7 @@ class JsonWalker(TreeWalker):
def serialize_html(input, options):
- options = dict([(str(k), v) for k, v in options.items()])
+ options = {str(k): v for k, v in options.items()}
encoding = options.get("encoding", None)
if "encoding" in options:
del options["encoding"]
@@ -89,19 +89,6 @@ def serialize_html(input, options):
return serializer.render(stream, encoding)
-def runSerializerTest(input, expected, options):
- encoding = options.get("encoding", None)
-
- if encoding:
- expected = list(map(lambda x: x.encode(encoding), expected))
-
- result = serialize_html(input, options)
- if len(expected) == 1:
- assert expected[0] == result, "Expected:\n%s\nActual:\n%s\nOptions:\n%s" % (expected[0], result, str(options))
- elif result not in expected:
- assert False, "Expected: %s, Received: %s" % (expected, result)
-
-
def throwsWithLatin1(input):
with pytest.raises(UnicodeEncodeError):
serialize_html(input, {"encoding": "iso-8859-1"})
@@ -120,13 +107,13 @@ def testDoctypeSystemId():
def testCdataCharacters():
- runSerializerTest([["StartTag", "http://www.w3.org/1999/xhtml", "style", {}], ["Characters", "\u0101"]],
- ["
-#encoding
-iso-8859-2
-
-#data
-
-
-#encoding
-iso-8859-2
-
-#data
-
-
-
-#encoding
-iso-8859-2
diff --git a/libs/html5lib/tests/testdata/encoding/tests2.dat b/libs/html5lib/tests/testdata/encoding/tests2.dat
deleted file mode 100644
index d31b387fb..000000000
--- a/libs/html5lib/tests/testdata/encoding/tests2.dat
+++ /dev/null
@@ -1,115 +0,0 @@
-#data
-
-#encoding
-utf-8
-
-#data
-
-
-#encoding
-windows-1252
-
-#data
-
-#encoding
-utf-8
-
-#data
-
-#encoding
-windows-1252
-
-#data
-
-#encoding
-utf-8
-
-#data
-
-#encoding
-utf-8
-
-#data
-
-#encoding
-utf-8
-
-#data
-
-#encoding
-utf-8
-
-#data
-
-
-#encoding
-utf-8
-
-#data
-
-
-#encoding
-utf-8
-
-#data
-ñ
-
-#encoding
-utf-8
diff --git a/libs/html5lib/tests/testdata/serializer/core.test b/libs/html5lib/tests/testdata/serializer/core.test
deleted file mode 100644
index e1e3be043..000000000
--- a/libs/html5lib/tests/testdata/serializer/core.test
+++ /dev/null
@@ -1,125 +0,0 @@
-{"tests": [
-
-{"description": "proper attribute value escaping",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "test \"with\" ""}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value non-quoting",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo"}]]],
- "expected": [""],
- "xhtml": [""]
-},
-
-{"description": "proper attribute value non-quoting (with <)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo"],
- "xhtml": [""]
-},
-
-{"description": "proper attribute value quoting (with =)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo=bar"}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value quoting (with >)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo>bar"}]]],
- "expected": ["bar\">"]
-},
-
-{"description": "proper attribute value quoting (with \")",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo\"bar"}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value quoting (with ')",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo'bar"}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value quoting (with both \" and ')",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo'bar\"baz"}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value quoting (with space)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo bar"}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value quoting (with tab)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo\tbar"}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value quoting (with LF)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo\nbar"}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value quoting (with CR)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo\rbar"}]]],
- "expected": [""]
-},
-
-{"description": "proper attribute value non-quoting (with linetab)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo\u000Bbar"}]]],
- "expected": [""],
- "xhtml": [""]
-},
-
-{"description": "proper attribute value quoting (with form feed)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "span", [{"namespace": null, "name": "title", "value": "foo\u000Cbar"}]]],
- "expected": [""]
-},
-
-{"description": "void element (as EmptyTag token)",
- "input": [["EmptyTag", "img", {}]],
- "expected": [""],
- "xhtml": [""]
-},
-
-{"description": "void element (as StartTag token)",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "img", {}]],
- "expected": [""],
- "xhtml": [""]
-},
-
-{"description": "doctype in error",
- "input": [["Doctype", "foo"]],
- "expected": [""]
-},
-
-{"description": "character data",
- "options": {"encoding":"utf-8"},
- "input": [["Characters", "ac&d"]],
- "expected": ["a<b>c&d"]
-},
-
-{"description": "rcdata",
- "input": [["StartTag", "http://www.w3.org/1999/xhtml", "script", {}], ["Characters", "ac&d"]],
- "expected": [""]
-},
-
-{"description": "text within "]
-}
-
-]}
\ No newline at end of file
diff --git a/libs/html5lib/tests/testdata/tokenizer/README.md b/libs/html5lib/tests/testdata/tokenizer/README.md
deleted file mode 100644
index 4218c26bb..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/README.md
+++ /dev/null
@@ -1,104 +0,0 @@
-Tokenizer tests
-===============
-
-The test format is [JSON](http://www.json.org/). This has the advantage
-that the syntax allows backward-compatible extensions to the tests and
-the disadvantage that it is relatively verbose.
-
-Basic Structure
----------------
-
- {"tests": [
- {"description": "Test description",
- "input": "input_string",
- "output": [expected_output_tokens],
- "initialStates": [initial_states],
- "lastStartTag": last_start_tag,
- "ignoreErrorOrder": ignore_error_order
- }
- ]}
-
-Multiple tests per file are allowed simply by adding more objects to the
-"tests" list.
-
-`description`, `input` and `output` are always present. The other values
-are optional.
-
-### Test set-up
-
-`test.input` is a string containing the characters to pass to the
-tokenizer. Specifically, it represents the characters of the **input
-stream**, and so implementations are expected to perform the processing
-described in the spec's **Preprocessing the input stream** section
-before feeding the result to the tokenizer.
-
-If `test.doubleEscaped` is present and `true`, then `test.input` is not
-quite as described above. Instead, it must first be subjected to another
-round of unescaping (i.e., in addition to any unescaping involved in the
-JSON import), and the result of *that* represents the characters of the
-input stream. Currently, the only unescaping required by this option is
-to convert each sequence of the form \\uHHHH (where H is a hex digit)
-into the corresponding Unicode code point. (Note that this option also
-affects the interpretation of `test.output`.)
-
-`test.initialStates` is a list of strings, each being the name of a
-tokenizer state. The test should be run once for each string, using it
-to set the tokenizer's initial state for that run. If
-`test.initialStates` is omitted, it defaults to `["data state"]`.
-
-`test.lastStartTag` is a lowercase string that should be used as "the
-tag name of the last start tag to have been emitted from this
-tokenizer", referenced in the spec's definition of **appropriate end tag
-token**. If it is omitted, it is treated as if "no start tag has been
-emitted from this tokenizer".
-
-### Test results
-
-`test.output` is a list of tokens, ordered with the first produced by
-the tokenizer the first (leftmost) in the list. The list must mach the
-**complete** list of tokens that the tokenizer should produce. Valid
-tokens are:
-
- ["DOCTYPE", name, public_id, system_id, correctness]
- ["StartTag", name, {attributes}*, true*]
- ["StartTag", name, {attributes}]
- ["EndTag", name]
- ["Comment", data]
- ["Character", data]
- "ParseError"
-
-`public_id` and `system_id` are either strings or `null`. `correctness`
-is either `true` or `false`; `true` corresponds to the force-quirks flag
-being false, and vice-versa.
-
-When the self-closing flag is set, the `StartTag` array has `true` as
-its fourth entry. When the flag is not set, the array has only three
-entries for backwards compatibility.
-
-All adjacent character tokens are coalesced into a single
-`["Character", data]` token.
-
-If `test.doubleEscaped` is present and `true`, then every string within
-`test.output` must be further unescaped (as described above) before
-comparing with the tokenizer's output.
-
-`test.ignoreErrorOrder` is a boolean value indicating that the order of
-`ParseError` tokens relative to other tokens in the output stream is
-unimportant, and implementations should ignore such differences between
-their output and `expected_output_tokens`. (This is used for errors
-emitted by the input stream preprocessing stage, since it is useful to
-test that code but it is undefined when the errors occur). If it is
-omitted, it defaults to `false`.
-
-xmlViolation tests
-------------------
-
-`tokenizer/xmlViolation.test` differs from the above in a couple of
-ways:
-
-- The name of the single member of the top-level JSON object is
- "xmlViolationTests" instead of "tests".
-- Each test's expected output assumes that implementation is applying
- the tweaks given in the spec's "Coercing an HTML DOM into an
- infoset" section.
-
diff --git a/libs/html5lib/tests/testdata/tokenizer/contentModelFlags.test b/libs/html5lib/tests/testdata/tokenizer/contentModelFlags.test
deleted file mode 100644
index 89b8170c6..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/contentModelFlags.test
+++ /dev/null
@@ -1,81 +0,0 @@
-{"tests": [
-
-{"description":"PLAINTEXT content model flag",
-"initialStates":["PLAINTEXT state"],
-"lastStartTag":"plaintext",
-"input":"&body;",
-"output":[["Character", "&body;"]]},
-
-{"description":"End tag closing RCDATA or RAWTEXT",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"foo",
-"output":[["Character", "foo"], ["EndTag", "xmp"]]},
-
-{"description":"End tag closing RCDATA or RAWTEXT (case-insensitivity)",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"foo",
-"output":[["Character", "foo"], ["EndTag", "xmp"]]},
-
-{"description":"End tag closing RCDATA or RAWTEXT (ending with space)",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"foobar",
-"output":[["Character", "bar"], ["EndTag", "xmp"]]},
-
-{"description":"Partial end tags leading straight into partial end tags",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"",
-"output":[["Character", "bar",
-"output":[["Character", "bar"]]},
-
-{"description":"End tag closing RCDATA or RAWTEXT, switching back to PCDATA",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"foo",
-"output":[["Character", "foo"], ["EndTag", "xmp"], ["EndTag", "baz"]]},
-
-{"description":"RAWTEXT w/ something looking like an entity",
-"initialStates":["RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"&foo;",
-"output":[["Character", "&foo;"]]},
-
-{"description":"RCDATA w/ an entity",
-"initialStates":["RCDATA state"],
-"lastStartTag":"textarea",
-"input":"<",
-"output":[["Character", "<"]]}
-
-]}
diff --git a/libs/html5lib/tests/testdata/tokenizer/domjs.test b/libs/html5lib/tests/testdata/tokenizer/domjs.test
deleted file mode 100644
index 8f1e42f35..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/domjs.test
+++ /dev/null
@@ -1,96 +0,0 @@
-{
- "tests": [
- {
- "description":"CR in bogus comment state",
- "input":"\u000d",
- "output":["ParseError", ["Comment", "?\u000a"]]
- },
- {
- "description":"CRLF in bogus comment state",
- "input":"\u000d\u000a",
- "output":["ParseError", ["Comment", "?\u000a"]]
- },
- {
- "description":"CRLFLF in bogus comment state",
- "input":"\u000d\u000a\u000a",
- "output":["ParseError", ["Comment", "?\u000a\u000a"]]
- },
- {
- "description":"NUL in RCDATA and RAWTEXT",
- "doubleEscaped":true,
- "initialStates":["RCDATA state", "RAWTEXT state"],
- "input":"\\u0000",
- "output":["ParseError", ["Character", "\\uFFFD"]]
- },
- {
- "description":"leading U+FEFF must pass through",
- "doubleEscaped":true,
- "input":"\\uFEFFfoo\\uFEFFbar",
- "output":[["Character", "\\uFEFFfoo\\uFEFFbar"]]
- },
- {
- "description":"Non BMP-charref in in RCDATA",
- "initialStates":["RCDATA state"],
- "input":"≂̸",
- "output":[["Character", "\u2242\u0338"]]
- },
- {
- "description":"Bad charref in in RCDATA",
- "initialStates":["RCDATA state"],
- "input":"&NotEqualTild;",
- "output":["ParseError", ["Character", "&NotEqualTild;"]]
- },
- {
- "description":"lowercase endtags in RCDATA and RAWTEXT",
- "initialStates":["RCDATA state", "RAWTEXT state"],
- "lastStartTag":"xmp",
- "input":"",
- "output":[["EndTag","xmp"]]
- },
- {
- "description":"bad endtag in RCDATA and RAWTEXT",
- "initialStates":["RCDATA state", "RAWTEXT state"],
- "lastStartTag":"xmp",
- "input":" XMP>",
- "output":[["Character"," XMP>"]]
- },
- {
- "description":"bad endtag in RCDATA and RAWTEXT",
- "initialStates":["RCDATA state", "RAWTEXT state"],
- "lastStartTag":"xmp",
- "input":"",
- "output":[["Character",""]]
- },
- {
- "description":"bad endtag in RCDATA and RAWTEXT",
- "initialStates":["RCDATA state", "RAWTEXT state"],
- "lastStartTag":"xmp",
- "input":"",
- "output":[["StartTag", "p", {"id":"\u2242\u0338"}]]
- },
- {
- "description":"--!NUL in comment ",
- "doubleEscaped":true,
- "input":"",
- "output":["ParseError", "ParseError", ["Comment", "--!\\uFFFD"]]
- },
- {
- "description":"space EOF after doctype ",
- "input":"",
-"output": [["StartTag", "h", {"a": "¬i;"}]]},
-
-{"description": "Entity name followed by the equals sign in an attribute value.",
-"input":"",
-"output": [["StartTag", "h", {"a": "&lang="}]]},
-
-{"description": "CR as numeric entity",
-"input":"
",
-"output": ["ParseError", ["Character", "\r"]]},
-
-{"description": "CR as hexadecimal numeric entity",
-"input":"
",
-"output": ["ParseError", ["Character", "\r"]]},
-
-{"description": "Windows-1252 EURO SIGN numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u20AC"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0081"]]},
-
-{"description": "Windows-1252 SINGLE LOW-9 QUOTATION MARK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u201A"]]},
-
-{"description": "Windows-1252 LATIN SMALL LETTER F WITH HOOK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0192"]]},
-
-{"description": "Windows-1252 DOUBLE LOW-9 QUOTATION MARK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u201E"]]},
-
-{"description": "Windows-1252 HORIZONTAL ELLIPSIS numeric entity.",
-"input":"
",
-"output": ["ParseError", ["Character", "\u2026"]]},
-
-{"description": "Windows-1252 DAGGER numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2020"]]},
-
-{"description": "Windows-1252 DOUBLE DAGGER numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2021"]]},
-
-{"description": "Windows-1252 MODIFIER LETTER CIRCUMFLEX ACCENT numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u02C6"]]},
-
-{"description": "Windows-1252 PER MILLE SIGN numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2030"]]},
-
-{"description": "Windows-1252 LATIN CAPITAL LETTER S WITH CARON numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0160"]]},
-
-{"description": "Windows-1252 SINGLE LEFT-POINTING ANGLE QUOTATION MARK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2039"]]},
-
-{"description": "Windows-1252 LATIN CAPITAL LIGATURE OE numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0152"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u008D"]]},
-
-{"description": "Windows-1252 LATIN CAPITAL LETTER Z WITH CARON numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u017D"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u008F"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0090"]]},
-
-{"description": "Windows-1252 LEFT SINGLE QUOTATION MARK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2018"]]},
-
-{"description": "Windows-1252 RIGHT SINGLE QUOTATION MARK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2019"]]},
-
-{"description": "Windows-1252 LEFT DOUBLE QUOTATION MARK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u201C"]]},
-
-{"description": "Windows-1252 RIGHT DOUBLE QUOTATION MARK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u201D"]]},
-
-{"description": "Windows-1252 BULLET numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2022"]]},
-
-{"description": "Windows-1252 EN DASH numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2013"]]},
-
-{"description": "Windows-1252 EM DASH numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2014"]]},
-
-{"description": "Windows-1252 SMALL TILDE numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u02DC"]]},
-
-{"description": "Windows-1252 TRADE MARK SIGN numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2122"]]},
-
-{"description": "Windows-1252 LATIN SMALL LETTER S WITH CARON numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0161"]]},
-
-{"description": "Windows-1252 SINGLE RIGHT-POINTING ANGLE QUOTATION MARK numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u203A"]]},
-
-{"description": "Windows-1252 LATIN SMALL LIGATURE OE numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0153"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u009D"]]},
-
-{"description": "Windows-1252 EURO SIGN hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u20AC"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0081"]]},
-
-{"description": "Windows-1252 SINGLE LOW-9 QUOTATION MARK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u201A"]]},
-
-{"description": "Windows-1252 LATIN SMALL LETTER F WITH HOOK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0192"]]},
-
-{"description": "Windows-1252 DOUBLE LOW-9 QUOTATION MARK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u201E"]]},
-
-{"description": "Windows-1252 HORIZONTAL ELLIPSIS hexadecimal numeric entity.",
-"input":"
",
-"output": ["ParseError", ["Character", "\u2026"]]},
-
-{"description": "Windows-1252 DAGGER hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2020"]]},
-
-{"description": "Windows-1252 DOUBLE DAGGER hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2021"]]},
-
-{"description": "Windows-1252 MODIFIER LETTER CIRCUMFLEX ACCENT hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u02C6"]]},
-
-{"description": "Windows-1252 PER MILLE SIGN hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2030"]]},
-
-{"description": "Windows-1252 LATIN CAPITAL LETTER S WITH CARON hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0160"]]},
-
-{"description": "Windows-1252 SINGLE LEFT-POINTING ANGLE QUOTATION MARK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2039"]]},
-
-{"description": "Windows-1252 LATIN CAPITAL LIGATURE OE hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0152"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u008D"]]},
-
-{"description": "Windows-1252 LATIN CAPITAL LETTER Z WITH CARON hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u017D"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u008F"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0090"]]},
-
-{"description": "Windows-1252 LEFT SINGLE QUOTATION MARK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2018"]]},
-
-{"description": "Windows-1252 RIGHT SINGLE QUOTATION MARK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2019"]]},
-
-{"description": "Windows-1252 LEFT DOUBLE QUOTATION MARK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u201C"]]},
-
-{"description": "Windows-1252 RIGHT DOUBLE QUOTATION MARK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u201D"]]},
-
-{"description": "Windows-1252 BULLET hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2022"]]},
-
-{"description": "Windows-1252 EN DASH hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2013"]]},
-
-{"description": "Windows-1252 EM DASH hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2014"]]},
-
-{"description": "Windows-1252 SMALL TILDE hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u02DC"]]},
-
-{"description": "Windows-1252 TRADE MARK SIGN hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u2122"]]},
-
-{"description": "Windows-1252 LATIN SMALL LETTER S WITH CARON hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0161"]]},
-
-{"description": "Windows-1252 SINGLE RIGHT-POINTING ANGLE QUOTATION MARK hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u203A"]]},
-
-{"description": "Windows-1252 LATIN SMALL LIGATURE OE hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0153"]]},
-
-{"description": "Windows-1252 REPLACEMENT CHAR hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u009D"]]},
-
-{"description": "Windows-1252 LATIN SMALL LETTER Z WITH CARON hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u017E"]]},
-
-{"description": "Windows-1252 LATIN CAPITAL LETTER Y WITH DIAERESIS hexadecimal numeric entity.",
-"input":"",
-"output": ["ParseError", ["Character", "\u0178"]]},
-
-{"description": "Decimal numeric entity followed by hex character a.",
-"input":"aa",
-"output": ["ParseError", ["Character", "aa"]]},
-
-{"description": "Decimal numeric entity followed by hex character A.",
-"input":"aA",
-"output": ["ParseError", ["Character", "aA"]]},
-
-{"description": "Decimal numeric entity followed by hex character f.",
-"input":"af",
-"output": ["ParseError", ["Character", "af"]]},
-
-{"description": "Decimal numeric entity followed by hex character A.",
-"input":"aF",
-"output": ["ParseError", ["Character", "aF"]]}
-
-]}
diff --git a/libs/html5lib/tests/testdata/tokenizer/escapeFlag.test b/libs/html5lib/tests/testdata/tokenizer/escapeFlag.test
deleted file mode 100644
index 18cb4309e..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/escapeFlag.test
+++ /dev/null
@@ -1,33 +0,0 @@
-{"tests": [
-
-{"description":"Commented close tag in RCDATA or RAWTEXT",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"foo",
-"output":[["Character", "foo"], ["EndTag", "xmp"]]},
-
-{"description":"Bogus comment in RCDATA or RAWTEXT",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"foobaz",
-"output":[["Character", "foobaz"], ["EndTag", "xmp"]]},
-
-{"description":"End tag surrounded by bogus comment in RCDATA or RAWTEXT",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"foobaz",
-"output":[["Character", "foo"], ["EndTag", "xmp"], "ParseError", ["Comment", ""], ["Character", "baz"], ["EndTag", "xmp"]]},
-
-{"description":"Commented entities in RCDATA",
-"initialStates":["RCDATA state"],
-"lastStartTag":"xmp",
-"input":" & & ",
-"output":[["Character", " & & "], ["EndTag", "xmp"]]},
-
-{"description":"Incorrect comment ending sequences in RCDATA or RAWTEXT",
-"initialStates":["RCDATA state", "RAWTEXT state"],
-"lastStartTag":"xmp",
-"input":"foox--<>",
-"output":[["Character", "foox--<>"], ["EndTag", "xmp"]]}
-
-]}
diff --git a/libs/html5lib/tests/testdata/tokenizer/namedEntities.test b/libs/html5lib/tests/testdata/tokenizer/namedEntities.test
deleted file mode 100644
index 14db2ede0..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/namedEntities.test
+++ /dev/null
@@ -1,42210 +0,0 @@
-{
- "tests": [
- {
- "input": "Æ",
- "description": "Named entity: AElig without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c6"
- ]
- ]
- },
- {
- "input": "Æ",
- "description": "Named entity: AElig; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c6"
- ]
- ]
- },
- {
- "input": "&",
- "description": "Named entity: AMP without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "&"
- ]
- ]
- },
- {
- "input": "&",
- "description": "Named entity: AMP; with a semi-colon",
- "output": [
- [
- "Character",
- "&"
- ]
- ]
- },
- {
- "input": "Á",
- "description": "Named entity: Aacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c1"
- ]
- ]
- },
- {
- "input": "Á",
- "description": "Named entity: Aacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c1"
- ]
- ]
- },
- {
- "input": "&Abreve",
- "description": "Bad named entity: Abreve without a semi-colon",
- "output": [
- [
- "Character",
- "&Abreve"
- ]
- ]
- },
- {
- "input": "Ă",
- "description": "Named entity: Abreve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0102"
- ]
- ]
- },
- {
- "input": "Â",
- "description": "Named entity: Acirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c2"
- ]
- ]
- },
- {
- "input": "Â",
- "description": "Named entity: Acirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c2"
- ]
- ]
- },
- {
- "input": "&Acy",
- "description": "Bad named entity: Acy without a semi-colon",
- "output": [
- [
- "Character",
- "&Acy"
- ]
- ]
- },
- {
- "input": "А",
- "description": "Named entity: Acy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0410"
- ]
- ]
- },
- {
- "input": "&Afr",
- "description": "Bad named entity: Afr without a semi-colon",
- "output": [
- [
- "Character",
- "&Afr"
- ]
- ]
- },
- {
- "input": "𝔄",
- "description": "Named entity: Afr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd04"
- ]
- ]
- },
- {
- "input": "À",
- "description": "Named entity: Agrave without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c0"
- ]
- ]
- },
- {
- "input": "À",
- "description": "Named entity: Agrave; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c0"
- ]
- ]
- },
- {
- "input": "&Alpha",
- "description": "Bad named entity: Alpha without a semi-colon",
- "output": [
- [
- "Character",
- "&Alpha"
- ]
- ]
- },
- {
- "input": "Α",
- "description": "Named entity: Alpha; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0391"
- ]
- ]
- },
- {
- "input": "&Amacr",
- "description": "Bad named entity: Amacr without a semi-colon",
- "output": [
- [
- "Character",
- "&Amacr"
- ]
- ]
- },
- {
- "input": "Ā",
- "description": "Named entity: Amacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0100"
- ]
- ]
- },
- {
- "input": "&And",
- "description": "Bad named entity: And without a semi-colon",
- "output": [
- [
- "Character",
- "&And"
- ]
- ]
- },
- {
- "input": "⩓",
- "description": "Named entity: And; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a53"
- ]
- ]
- },
- {
- "input": "&Aogon",
- "description": "Bad named entity: Aogon without a semi-colon",
- "output": [
- [
- "Character",
- "&Aogon"
- ]
- ]
- },
- {
- "input": "Ą",
- "description": "Named entity: Aogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0104"
- ]
- ]
- },
- {
- "input": "&Aopf",
- "description": "Bad named entity: Aopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Aopf"
- ]
- ]
- },
- {
- "input": "𝔸",
- "description": "Named entity: Aopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd38"
- ]
- ]
- },
- {
- "input": "&ApplyFunction",
- "description": "Bad named entity: ApplyFunction without a semi-colon",
- "output": [
- [
- "Character",
- "&ApplyFunction"
- ]
- ]
- },
- {
- "input": "⁡",
- "description": "Named entity: ApplyFunction; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2061"
- ]
- ]
- },
- {
- "input": "Å",
- "description": "Named entity: Aring without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c5"
- ]
- ]
- },
- {
- "input": "Å",
- "description": "Named entity: Aring; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c5"
- ]
- ]
- },
- {
- "input": "&Ascr",
- "description": "Bad named entity: Ascr without a semi-colon",
- "output": [
- [
- "Character",
- "&Ascr"
- ]
- ]
- },
- {
- "input": "𝒜",
- "description": "Named entity: Ascr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udc9c"
- ]
- ]
- },
- {
- "input": "&Assign",
- "description": "Bad named entity: Assign without a semi-colon",
- "output": [
- [
- "Character",
- "&Assign"
- ]
- ]
- },
- {
- "input": "≔",
- "description": "Named entity: Assign; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2254"
- ]
- ]
- },
- {
- "input": "Ã",
- "description": "Named entity: Atilde without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c3"
- ]
- ]
- },
- {
- "input": "Ã",
- "description": "Named entity: Atilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c3"
- ]
- ]
- },
- {
- "input": "Ä",
- "description": "Named entity: Auml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c4"
- ]
- ]
- },
- {
- "input": "Ä",
- "description": "Named entity: Auml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c4"
- ]
- ]
- },
- {
- "input": "&Backslash",
- "description": "Bad named entity: Backslash without a semi-colon",
- "output": [
- [
- "Character",
- "&Backslash"
- ]
- ]
- },
- {
- "input": "∖",
- "description": "Named entity: Backslash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2216"
- ]
- ]
- },
- {
- "input": "&Barv",
- "description": "Bad named entity: Barv without a semi-colon",
- "output": [
- [
- "Character",
- "&Barv"
- ]
- ]
- },
- {
- "input": "⫧",
- "description": "Named entity: Barv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ae7"
- ]
- ]
- },
- {
- "input": "&Barwed",
- "description": "Bad named entity: Barwed without a semi-colon",
- "output": [
- [
- "Character",
- "&Barwed"
- ]
- ]
- },
- {
- "input": "⌆",
- "description": "Named entity: Barwed; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2306"
- ]
- ]
- },
- {
- "input": "&Bcy",
- "description": "Bad named entity: Bcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Bcy"
- ]
- ]
- },
- {
- "input": "Б",
- "description": "Named entity: Bcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0411"
- ]
- ]
- },
- {
- "input": "&Because",
- "description": "Bad named entity: Because without a semi-colon",
- "output": [
- [
- "Character",
- "&Because"
- ]
- ]
- },
- {
- "input": "∵",
- "description": "Named entity: Because; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2235"
- ]
- ]
- },
- {
- "input": "&Bernoullis",
- "description": "Bad named entity: Bernoullis without a semi-colon",
- "output": [
- [
- "Character",
- "&Bernoullis"
- ]
- ]
- },
- {
- "input": "ℬ",
- "description": "Named entity: Bernoullis; with a semi-colon",
- "output": [
- [
- "Character",
- "\u212c"
- ]
- ]
- },
- {
- "input": "&Beta",
- "description": "Bad named entity: Beta without a semi-colon",
- "output": [
- [
- "Character",
- "&Beta"
- ]
- ]
- },
- {
- "input": "Β",
- "description": "Named entity: Beta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0392"
- ]
- ]
- },
- {
- "input": "&Bfr",
- "description": "Bad named entity: Bfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Bfr"
- ]
- ]
- },
- {
- "input": "𝔅",
- "description": "Named entity: Bfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd05"
- ]
- ]
- },
- {
- "input": "&Bopf",
- "description": "Bad named entity: Bopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Bopf"
- ]
- ]
- },
- {
- "input": "𝔹",
- "description": "Named entity: Bopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd39"
- ]
- ]
- },
- {
- "input": "&Breve",
- "description": "Bad named entity: Breve without a semi-colon",
- "output": [
- [
- "Character",
- "&Breve"
- ]
- ]
- },
- {
- "input": "˘",
- "description": "Named entity: Breve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02d8"
- ]
- ]
- },
- {
- "input": "&Bscr",
- "description": "Bad named entity: Bscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Bscr"
- ]
- ]
- },
- {
- "input": "ℬ",
- "description": "Named entity: Bscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u212c"
- ]
- ]
- },
- {
- "input": "&Bumpeq",
- "description": "Bad named entity: Bumpeq without a semi-colon",
- "output": [
- [
- "Character",
- "&Bumpeq"
- ]
- ]
- },
- {
- "input": "≎",
- "description": "Named entity: Bumpeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224e"
- ]
- ]
- },
- {
- "input": "&CHcy",
- "description": "Bad named entity: CHcy without a semi-colon",
- "output": [
- [
- "Character",
- "&CHcy"
- ]
- ]
- },
- {
- "input": "Ч",
- "description": "Named entity: CHcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0427"
- ]
- ]
- },
- {
- "input": "©",
- "description": "Named entity: COPY without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a9"
- ]
- ]
- },
- {
- "input": "©",
- "description": "Named entity: COPY; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a9"
- ]
- ]
- },
- {
- "input": "&Cacute",
- "description": "Bad named entity: Cacute without a semi-colon",
- "output": [
- [
- "Character",
- "&Cacute"
- ]
- ]
- },
- {
- "input": "Ć",
- "description": "Named entity: Cacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0106"
- ]
- ]
- },
- {
- "input": "&Cap",
- "description": "Bad named entity: Cap without a semi-colon",
- "output": [
- [
- "Character",
- "&Cap"
- ]
- ]
- },
- {
- "input": "⋒",
- "description": "Named entity: Cap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d2"
- ]
- ]
- },
- {
- "input": "&CapitalDifferentialD",
- "description": "Bad named entity: CapitalDifferentialD without a semi-colon",
- "output": [
- [
- "Character",
- "&CapitalDifferentialD"
- ]
- ]
- },
- {
- "input": "ⅅ",
- "description": "Named entity: CapitalDifferentialD; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2145"
- ]
- ]
- },
- {
- "input": "&Cayleys",
- "description": "Bad named entity: Cayleys without a semi-colon",
- "output": [
- [
- "Character",
- "&Cayleys"
- ]
- ]
- },
- {
- "input": "ℭ",
- "description": "Named entity: Cayleys; with a semi-colon",
- "output": [
- [
- "Character",
- "\u212d"
- ]
- ]
- },
- {
- "input": "&Ccaron",
- "description": "Bad named entity: Ccaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Ccaron"
- ]
- ]
- },
- {
- "input": "Č",
- "description": "Named entity: Ccaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u010c"
- ]
- ]
- },
- {
- "input": "Ç",
- "description": "Named entity: Ccedil without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c7"
- ]
- ]
- },
- {
- "input": "Ç",
- "description": "Named entity: Ccedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c7"
- ]
- ]
- },
- {
- "input": "&Ccirc",
- "description": "Bad named entity: Ccirc without a semi-colon",
- "output": [
- [
- "Character",
- "&Ccirc"
- ]
- ]
- },
- {
- "input": "Ĉ",
- "description": "Named entity: Ccirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0108"
- ]
- ]
- },
- {
- "input": "&Cconint",
- "description": "Bad named entity: Cconint without a semi-colon",
- "output": [
- [
- "Character",
- "&Cconint"
- ]
- ]
- },
- {
- "input": "∰",
- "description": "Named entity: Cconint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2230"
- ]
- ]
- },
- {
- "input": "&Cdot",
- "description": "Bad named entity: Cdot without a semi-colon",
- "output": [
- [
- "Character",
- "&Cdot"
- ]
- ]
- },
- {
- "input": "Ċ",
- "description": "Named entity: Cdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u010a"
- ]
- ]
- },
- {
- "input": "&Cedilla",
- "description": "Bad named entity: Cedilla without a semi-colon",
- "output": [
- [
- "Character",
- "&Cedilla"
- ]
- ]
- },
- {
- "input": "¸",
- "description": "Named entity: Cedilla; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b8"
- ]
- ]
- },
- {
- "input": "&CenterDot",
- "description": "Bad named entity: CenterDot without a semi-colon",
- "output": [
- [
- "Character",
- "&CenterDot"
- ]
- ]
- },
- {
- "input": "·",
- "description": "Named entity: CenterDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b7"
- ]
- ]
- },
- {
- "input": "&Cfr",
- "description": "Bad named entity: Cfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Cfr"
- ]
- ]
- },
- {
- "input": "ℭ",
- "description": "Named entity: Cfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u212d"
- ]
- ]
- },
- {
- "input": "&Chi",
- "description": "Bad named entity: Chi without a semi-colon",
- "output": [
- [
- "Character",
- "&Chi"
- ]
- ]
- },
- {
- "input": "Χ",
- "description": "Named entity: Chi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a7"
- ]
- ]
- },
- {
- "input": "&CircleDot",
- "description": "Bad named entity: CircleDot without a semi-colon",
- "output": [
- [
- "Character",
- "&CircleDot"
- ]
- ]
- },
- {
- "input": "⊙",
- "description": "Named entity: CircleDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2299"
- ]
- ]
- },
- {
- "input": "&CircleMinus",
- "description": "Bad named entity: CircleMinus without a semi-colon",
- "output": [
- [
- "Character",
- "&CircleMinus"
- ]
- ]
- },
- {
- "input": "⊖",
- "description": "Named entity: CircleMinus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2296"
- ]
- ]
- },
- {
- "input": "&CirclePlus",
- "description": "Bad named entity: CirclePlus without a semi-colon",
- "output": [
- [
- "Character",
- "&CirclePlus"
- ]
- ]
- },
- {
- "input": "⊕",
- "description": "Named entity: CirclePlus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2295"
- ]
- ]
- },
- {
- "input": "&CircleTimes",
- "description": "Bad named entity: CircleTimes without a semi-colon",
- "output": [
- [
- "Character",
- "&CircleTimes"
- ]
- ]
- },
- {
- "input": "⊗",
- "description": "Named entity: CircleTimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2297"
- ]
- ]
- },
- {
- "input": "&ClockwiseContourIntegral",
- "description": "Bad named entity: ClockwiseContourIntegral without a semi-colon",
- "output": [
- [
- "Character",
- "&ClockwiseContourIntegral"
- ]
- ]
- },
- {
- "input": "∲",
- "description": "Named entity: ClockwiseContourIntegral; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2232"
- ]
- ]
- },
- {
- "input": "&CloseCurlyDoubleQuote",
- "description": "Bad named entity: CloseCurlyDoubleQuote without a semi-colon",
- "output": [
- [
- "Character",
- "&CloseCurlyDoubleQuote"
- ]
- ]
- },
- {
- "input": "”",
- "description": "Named entity: CloseCurlyDoubleQuote; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201d"
- ]
- ]
- },
- {
- "input": "&CloseCurlyQuote",
- "description": "Bad named entity: CloseCurlyQuote without a semi-colon",
- "output": [
- [
- "Character",
- "&CloseCurlyQuote"
- ]
- ]
- },
- {
- "input": "’",
- "description": "Named entity: CloseCurlyQuote; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2019"
- ]
- ]
- },
- {
- "input": "&Colon",
- "description": "Bad named entity: Colon without a semi-colon",
- "output": [
- [
- "Character",
- "&Colon"
- ]
- ]
- },
- {
- "input": "∷",
- "description": "Named entity: Colon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2237"
- ]
- ]
- },
- {
- "input": "&Colone",
- "description": "Bad named entity: Colone without a semi-colon",
- "output": [
- [
- "Character",
- "&Colone"
- ]
- ]
- },
- {
- "input": "⩴",
- "description": "Named entity: Colone; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a74"
- ]
- ]
- },
- {
- "input": "&Congruent",
- "description": "Bad named entity: Congruent without a semi-colon",
- "output": [
- [
- "Character",
- "&Congruent"
- ]
- ]
- },
- {
- "input": "≡",
- "description": "Named entity: Congruent; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2261"
- ]
- ]
- },
- {
- "input": "&Conint",
- "description": "Bad named entity: Conint without a semi-colon",
- "output": [
- [
- "Character",
- "&Conint"
- ]
- ]
- },
- {
- "input": "∯",
- "description": "Named entity: Conint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222f"
- ]
- ]
- },
- {
- "input": "&ContourIntegral",
- "description": "Bad named entity: ContourIntegral without a semi-colon",
- "output": [
- [
- "Character",
- "&ContourIntegral"
- ]
- ]
- },
- {
- "input": "∮",
- "description": "Named entity: ContourIntegral; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222e"
- ]
- ]
- },
- {
- "input": "&Copf",
- "description": "Bad named entity: Copf without a semi-colon",
- "output": [
- [
- "Character",
- "&Copf"
- ]
- ]
- },
- {
- "input": "ℂ",
- "description": "Named entity: Copf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2102"
- ]
- ]
- },
- {
- "input": "&Coproduct",
- "description": "Bad named entity: Coproduct without a semi-colon",
- "output": [
- [
- "Character",
- "&Coproduct"
- ]
- ]
- },
- {
- "input": "∐",
- "description": "Named entity: Coproduct; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2210"
- ]
- ]
- },
- {
- "input": "&CounterClockwiseContourIntegral",
- "description": "Bad named entity: CounterClockwiseContourIntegral without a semi-colon",
- "output": [
- [
- "Character",
- "&CounterClockwiseContourIntegral"
- ]
- ]
- },
- {
- "input": "∳",
- "description": "Named entity: CounterClockwiseContourIntegral; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2233"
- ]
- ]
- },
- {
- "input": "&Cross",
- "description": "Bad named entity: Cross without a semi-colon",
- "output": [
- [
- "Character",
- "&Cross"
- ]
- ]
- },
- {
- "input": "⨯",
- "description": "Named entity: Cross; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a2f"
- ]
- ]
- },
- {
- "input": "&Cscr",
- "description": "Bad named entity: Cscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Cscr"
- ]
- ]
- },
- {
- "input": "𝒞",
- "description": "Named entity: Cscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udc9e"
- ]
- ]
- },
- {
- "input": "&Cup",
- "description": "Bad named entity: Cup without a semi-colon",
- "output": [
- [
- "Character",
- "&Cup"
- ]
- ]
- },
- {
- "input": "⋓",
- "description": "Named entity: Cup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d3"
- ]
- ]
- },
- {
- "input": "&CupCap",
- "description": "Bad named entity: CupCap without a semi-colon",
- "output": [
- [
- "Character",
- "&CupCap"
- ]
- ]
- },
- {
- "input": "≍",
- "description": "Named entity: CupCap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224d"
- ]
- ]
- },
- {
- "input": "&DD",
- "description": "Bad named entity: DD without a semi-colon",
- "output": [
- [
- "Character",
- "&DD"
- ]
- ]
- },
- {
- "input": "ⅅ",
- "description": "Named entity: DD; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2145"
- ]
- ]
- },
- {
- "input": "&DDotrahd",
- "description": "Bad named entity: DDotrahd without a semi-colon",
- "output": [
- [
- "Character",
- "&DDotrahd"
- ]
- ]
- },
- {
- "input": "⤑",
- "description": "Named entity: DDotrahd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2911"
- ]
- ]
- },
- {
- "input": "&DJcy",
- "description": "Bad named entity: DJcy without a semi-colon",
- "output": [
- [
- "Character",
- "&DJcy"
- ]
- ]
- },
- {
- "input": "Ђ",
- "description": "Named entity: DJcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0402"
- ]
- ]
- },
- {
- "input": "&DScy",
- "description": "Bad named entity: DScy without a semi-colon",
- "output": [
- [
- "Character",
- "&DScy"
- ]
- ]
- },
- {
- "input": "Ѕ",
- "description": "Named entity: DScy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0405"
- ]
- ]
- },
- {
- "input": "&DZcy",
- "description": "Bad named entity: DZcy without a semi-colon",
- "output": [
- [
- "Character",
- "&DZcy"
- ]
- ]
- },
- {
- "input": "Џ",
- "description": "Named entity: DZcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u040f"
- ]
- ]
- },
- {
- "input": "&Dagger",
- "description": "Bad named entity: Dagger without a semi-colon",
- "output": [
- [
- "Character",
- "&Dagger"
- ]
- ]
- },
- {
- "input": "‡",
- "description": "Named entity: Dagger; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2021"
- ]
- ]
- },
- {
- "input": "&Darr",
- "description": "Bad named entity: Darr without a semi-colon",
- "output": [
- [
- "Character",
- "&Darr"
- ]
- ]
- },
- {
- "input": "↡",
- "description": "Named entity: Darr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a1"
- ]
- ]
- },
- {
- "input": "&Dashv",
- "description": "Bad named entity: Dashv without a semi-colon",
- "output": [
- [
- "Character",
- "&Dashv"
- ]
- ]
- },
- {
- "input": "⫤",
- "description": "Named entity: Dashv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ae4"
- ]
- ]
- },
- {
- "input": "&Dcaron",
- "description": "Bad named entity: Dcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Dcaron"
- ]
- ]
- },
- {
- "input": "Ď",
- "description": "Named entity: Dcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u010e"
- ]
- ]
- },
- {
- "input": "&Dcy",
- "description": "Bad named entity: Dcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Dcy"
- ]
- ]
- },
- {
- "input": "Д",
- "description": "Named entity: Dcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0414"
- ]
- ]
- },
- {
- "input": "&Del",
- "description": "Bad named entity: Del without a semi-colon",
- "output": [
- [
- "Character",
- "&Del"
- ]
- ]
- },
- {
- "input": "∇",
- "description": "Named entity: Del; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2207"
- ]
- ]
- },
- {
- "input": "&Delta",
- "description": "Bad named entity: Delta without a semi-colon",
- "output": [
- [
- "Character",
- "&Delta"
- ]
- ]
- },
- {
- "input": "Δ",
- "description": "Named entity: Delta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0394"
- ]
- ]
- },
- {
- "input": "&Dfr",
- "description": "Bad named entity: Dfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Dfr"
- ]
- ]
- },
- {
- "input": "𝔇",
- "description": "Named entity: Dfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd07"
- ]
- ]
- },
- {
- "input": "&DiacriticalAcute",
- "description": "Bad named entity: DiacriticalAcute without a semi-colon",
- "output": [
- [
- "Character",
- "&DiacriticalAcute"
- ]
- ]
- },
- {
- "input": "´",
- "description": "Named entity: DiacriticalAcute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b4"
- ]
- ]
- },
- {
- "input": "&DiacriticalDot",
- "description": "Bad named entity: DiacriticalDot without a semi-colon",
- "output": [
- [
- "Character",
- "&DiacriticalDot"
- ]
- ]
- },
- {
- "input": "˙",
- "description": "Named entity: DiacriticalDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02d9"
- ]
- ]
- },
- {
- "input": "&DiacriticalDoubleAcute",
- "description": "Bad named entity: DiacriticalDoubleAcute without a semi-colon",
- "output": [
- [
- "Character",
- "&DiacriticalDoubleAcute"
- ]
- ]
- },
- {
- "input": "˝",
- "description": "Named entity: DiacriticalDoubleAcute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02dd"
- ]
- ]
- },
- {
- "input": "&DiacriticalGrave",
- "description": "Bad named entity: DiacriticalGrave without a semi-colon",
- "output": [
- [
- "Character",
- "&DiacriticalGrave"
- ]
- ]
- },
- {
- "input": "`",
- "description": "Named entity: DiacriticalGrave; with a semi-colon",
- "output": [
- [
- "Character",
- "`"
- ]
- ]
- },
- {
- "input": "&DiacriticalTilde",
- "description": "Bad named entity: DiacriticalTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&DiacriticalTilde"
- ]
- ]
- },
- {
- "input": "˜",
- "description": "Named entity: DiacriticalTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02dc"
- ]
- ]
- },
- {
- "input": "&Diamond",
- "description": "Bad named entity: Diamond without a semi-colon",
- "output": [
- [
- "Character",
- "&Diamond"
- ]
- ]
- },
- {
- "input": "⋄",
- "description": "Named entity: Diamond; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c4"
- ]
- ]
- },
- {
- "input": "&DifferentialD",
- "description": "Bad named entity: DifferentialD without a semi-colon",
- "output": [
- [
- "Character",
- "&DifferentialD"
- ]
- ]
- },
- {
- "input": "ⅆ",
- "description": "Named entity: DifferentialD; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2146"
- ]
- ]
- },
- {
- "input": "&Dopf",
- "description": "Bad named entity: Dopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Dopf"
- ]
- ]
- },
- {
- "input": "𝔻",
- "description": "Named entity: Dopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd3b"
- ]
- ]
- },
- {
- "input": "&Dot",
- "description": "Bad named entity: Dot without a semi-colon",
- "output": [
- [
- "Character",
- "&Dot"
- ]
- ]
- },
- {
- "input": "¨",
- "description": "Named entity: Dot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a8"
- ]
- ]
- },
- {
- "input": "&DotDot",
- "description": "Bad named entity: DotDot without a semi-colon",
- "output": [
- [
- "Character",
- "&DotDot"
- ]
- ]
- },
- {
- "input": "⃜",
- "description": "Named entity: DotDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u20dc"
- ]
- ]
- },
- {
- "input": "&DotEqual",
- "description": "Bad named entity: DotEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&DotEqual"
- ]
- ]
- },
- {
- "input": "≐",
- "description": "Named entity: DotEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2250"
- ]
- ]
- },
- {
- "input": "&DoubleContourIntegral",
- "description": "Bad named entity: DoubleContourIntegral without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleContourIntegral"
- ]
- ]
- },
- {
- "input": "∯",
- "description": "Named entity: DoubleContourIntegral; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222f"
- ]
- ]
- },
- {
- "input": "&DoubleDot",
- "description": "Bad named entity: DoubleDot without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleDot"
- ]
- ]
- },
- {
- "input": "¨",
- "description": "Named entity: DoubleDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a8"
- ]
- ]
- },
- {
- "input": "&DoubleDownArrow",
- "description": "Bad named entity: DoubleDownArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleDownArrow"
- ]
- ]
- },
- {
- "input": "⇓",
- "description": "Named entity: DoubleDownArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d3"
- ]
- ]
- },
- {
- "input": "&DoubleLeftArrow",
- "description": "Bad named entity: DoubleLeftArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleLeftArrow"
- ]
- ]
- },
- {
- "input": "⇐",
- "description": "Named entity: DoubleLeftArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d0"
- ]
- ]
- },
- {
- "input": "&DoubleLeftRightArrow",
- "description": "Bad named entity: DoubleLeftRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleLeftRightArrow"
- ]
- ]
- },
- {
- "input": "⇔",
- "description": "Named entity: DoubleLeftRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d4"
- ]
- ]
- },
- {
- "input": "&DoubleLeftTee",
- "description": "Bad named entity: DoubleLeftTee without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleLeftTee"
- ]
- ]
- },
- {
- "input": "⫤",
- "description": "Named entity: DoubleLeftTee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ae4"
- ]
- ]
- },
- {
- "input": "&DoubleLongLeftArrow",
- "description": "Bad named entity: DoubleLongLeftArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleLongLeftArrow"
- ]
- ]
- },
- {
- "input": "⟸",
- "description": "Named entity: DoubleLongLeftArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f8"
- ]
- ]
- },
- {
- "input": "&DoubleLongLeftRightArrow",
- "description": "Bad named entity: DoubleLongLeftRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleLongLeftRightArrow"
- ]
- ]
- },
- {
- "input": "⟺",
- "description": "Named entity: DoubleLongLeftRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27fa"
- ]
- ]
- },
- {
- "input": "&DoubleLongRightArrow",
- "description": "Bad named entity: DoubleLongRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleLongRightArrow"
- ]
- ]
- },
- {
- "input": "⟹",
- "description": "Named entity: DoubleLongRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f9"
- ]
- ]
- },
- {
- "input": "&DoubleRightArrow",
- "description": "Bad named entity: DoubleRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleRightArrow"
- ]
- ]
- },
- {
- "input": "⇒",
- "description": "Named entity: DoubleRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d2"
- ]
- ]
- },
- {
- "input": "&DoubleRightTee",
- "description": "Bad named entity: DoubleRightTee without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleRightTee"
- ]
- ]
- },
- {
- "input": "⊨",
- "description": "Named entity: DoubleRightTee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a8"
- ]
- ]
- },
- {
- "input": "&DoubleUpArrow",
- "description": "Bad named entity: DoubleUpArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleUpArrow"
- ]
- ]
- },
- {
- "input": "⇑",
- "description": "Named entity: DoubleUpArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d1"
- ]
- ]
- },
- {
- "input": "&DoubleUpDownArrow",
- "description": "Bad named entity: DoubleUpDownArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleUpDownArrow"
- ]
- ]
- },
- {
- "input": "⇕",
- "description": "Named entity: DoubleUpDownArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d5"
- ]
- ]
- },
- {
- "input": "&DoubleVerticalBar",
- "description": "Bad named entity: DoubleVerticalBar without a semi-colon",
- "output": [
- [
- "Character",
- "&DoubleVerticalBar"
- ]
- ]
- },
- {
- "input": "∥",
- "description": "Named entity: DoubleVerticalBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2225"
- ]
- ]
- },
- {
- "input": "&DownArrow",
- "description": "Bad named entity: DownArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DownArrow"
- ]
- ]
- },
- {
- "input": "↓",
- "description": "Named entity: DownArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2193"
- ]
- ]
- },
- {
- "input": "&DownArrowBar",
- "description": "Bad named entity: DownArrowBar without a semi-colon",
- "output": [
- [
- "Character",
- "&DownArrowBar"
- ]
- ]
- },
- {
- "input": "⤓",
- "description": "Named entity: DownArrowBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2913"
- ]
- ]
- },
- {
- "input": "&DownArrowUpArrow",
- "description": "Bad named entity: DownArrowUpArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DownArrowUpArrow"
- ]
- ]
- },
- {
- "input": "⇵",
- "description": "Named entity: DownArrowUpArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21f5"
- ]
- ]
- },
- {
- "input": "&DownBreve",
- "description": "Bad named entity: DownBreve without a semi-colon",
- "output": [
- [
- "Character",
- "&DownBreve"
- ]
- ]
- },
- {
- "input": "̑",
- "description": "Named entity: DownBreve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0311"
- ]
- ]
- },
- {
- "input": "&DownLeftRightVector",
- "description": "Bad named entity: DownLeftRightVector without a semi-colon",
- "output": [
- [
- "Character",
- "&DownLeftRightVector"
- ]
- ]
- },
- {
- "input": "⥐",
- "description": "Named entity: DownLeftRightVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2950"
- ]
- ]
- },
- {
- "input": "&DownLeftTeeVector",
- "description": "Bad named entity: DownLeftTeeVector without a semi-colon",
- "output": [
- [
- "Character",
- "&DownLeftTeeVector"
- ]
- ]
- },
- {
- "input": "⥞",
- "description": "Named entity: DownLeftTeeVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u295e"
- ]
- ]
- },
- {
- "input": "&DownLeftVector",
- "description": "Bad named entity: DownLeftVector without a semi-colon",
- "output": [
- [
- "Character",
- "&DownLeftVector"
- ]
- ]
- },
- {
- "input": "↽",
- "description": "Named entity: DownLeftVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bd"
- ]
- ]
- },
- {
- "input": "&DownLeftVectorBar",
- "description": "Bad named entity: DownLeftVectorBar without a semi-colon",
- "output": [
- [
- "Character",
- "&DownLeftVectorBar"
- ]
- ]
- },
- {
- "input": "⥖",
- "description": "Named entity: DownLeftVectorBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2956"
- ]
- ]
- },
- {
- "input": "&DownRightTeeVector",
- "description": "Bad named entity: DownRightTeeVector without a semi-colon",
- "output": [
- [
- "Character",
- "&DownRightTeeVector"
- ]
- ]
- },
- {
- "input": "⥟",
- "description": "Named entity: DownRightTeeVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u295f"
- ]
- ]
- },
- {
- "input": "&DownRightVector",
- "description": "Bad named entity: DownRightVector without a semi-colon",
- "output": [
- [
- "Character",
- "&DownRightVector"
- ]
- ]
- },
- {
- "input": "⇁",
- "description": "Named entity: DownRightVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c1"
- ]
- ]
- },
- {
- "input": "&DownRightVectorBar",
- "description": "Bad named entity: DownRightVectorBar without a semi-colon",
- "output": [
- [
- "Character",
- "&DownRightVectorBar"
- ]
- ]
- },
- {
- "input": "⥗",
- "description": "Named entity: DownRightVectorBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2957"
- ]
- ]
- },
- {
- "input": "&DownTee",
- "description": "Bad named entity: DownTee without a semi-colon",
- "output": [
- [
- "Character",
- "&DownTee"
- ]
- ]
- },
- {
- "input": "⊤",
- "description": "Named entity: DownTee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a4"
- ]
- ]
- },
- {
- "input": "&DownTeeArrow",
- "description": "Bad named entity: DownTeeArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&DownTeeArrow"
- ]
- ]
- },
- {
- "input": "↧",
- "description": "Named entity: DownTeeArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a7"
- ]
- ]
- },
- {
- "input": "&Downarrow",
- "description": "Bad named entity: Downarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Downarrow"
- ]
- ]
- },
- {
- "input": "⇓",
- "description": "Named entity: Downarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d3"
- ]
- ]
- },
- {
- "input": "&Dscr",
- "description": "Bad named entity: Dscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Dscr"
- ]
- ]
- },
- {
- "input": "𝒟",
- "description": "Named entity: Dscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udc9f"
- ]
- ]
- },
- {
- "input": "&Dstrok",
- "description": "Bad named entity: Dstrok without a semi-colon",
- "output": [
- [
- "Character",
- "&Dstrok"
- ]
- ]
- },
- {
- "input": "Đ",
- "description": "Named entity: Dstrok; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0110"
- ]
- ]
- },
- {
- "input": "&ENG",
- "description": "Bad named entity: ENG without a semi-colon",
- "output": [
- [
- "Character",
- "&ENG"
- ]
- ]
- },
- {
- "input": "Ŋ",
- "description": "Named entity: ENG; with a semi-colon",
- "output": [
- [
- "Character",
- "\u014a"
- ]
- ]
- },
- {
- "input": "Ð",
- "description": "Named entity: ETH without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d0"
- ]
- ]
- },
- {
- "input": "Ð",
- "description": "Named entity: ETH; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d0"
- ]
- ]
- },
- {
- "input": "É",
- "description": "Named entity: Eacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c9"
- ]
- ]
- },
- {
- "input": "É",
- "description": "Named entity: Eacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c9"
- ]
- ]
- },
- {
- "input": "&Ecaron",
- "description": "Bad named entity: Ecaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Ecaron"
- ]
- ]
- },
- {
- "input": "Ě",
- "description": "Named entity: Ecaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u011a"
- ]
- ]
- },
- {
- "input": "Ê",
- "description": "Named entity: Ecirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ca"
- ]
- ]
- },
- {
- "input": "Ê",
- "description": "Named entity: Ecirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ca"
- ]
- ]
- },
- {
- "input": "&Ecy",
- "description": "Bad named entity: Ecy without a semi-colon",
- "output": [
- [
- "Character",
- "&Ecy"
- ]
- ]
- },
- {
- "input": "Э",
- "description": "Named entity: Ecy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u042d"
- ]
- ]
- },
- {
- "input": "&Edot",
- "description": "Bad named entity: Edot without a semi-colon",
- "output": [
- [
- "Character",
- "&Edot"
- ]
- ]
- },
- {
- "input": "Ė",
- "description": "Named entity: Edot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0116"
- ]
- ]
- },
- {
- "input": "&Efr",
- "description": "Bad named entity: Efr without a semi-colon",
- "output": [
- [
- "Character",
- "&Efr"
- ]
- ]
- },
- {
- "input": "𝔈",
- "description": "Named entity: Efr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd08"
- ]
- ]
- },
- {
- "input": "È",
- "description": "Named entity: Egrave without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00c8"
- ]
- ]
- },
- {
- "input": "È",
- "description": "Named entity: Egrave; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c8"
- ]
- ]
- },
- {
- "input": "&Element",
- "description": "Bad named entity: Element without a semi-colon",
- "output": [
- [
- "Character",
- "&Element"
- ]
- ]
- },
- {
- "input": "∈",
- "description": "Named entity: Element; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2208"
- ]
- ]
- },
- {
- "input": "&Emacr",
- "description": "Bad named entity: Emacr without a semi-colon",
- "output": [
- [
- "Character",
- "&Emacr"
- ]
- ]
- },
- {
- "input": "Ē",
- "description": "Named entity: Emacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0112"
- ]
- ]
- },
- {
- "input": "&EmptySmallSquare",
- "description": "Bad named entity: EmptySmallSquare without a semi-colon",
- "output": [
- [
- "Character",
- "&EmptySmallSquare"
- ]
- ]
- },
- {
- "input": "◻",
- "description": "Named entity: EmptySmallSquare; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25fb"
- ]
- ]
- },
- {
- "input": "&EmptyVerySmallSquare",
- "description": "Bad named entity: EmptyVerySmallSquare without a semi-colon",
- "output": [
- [
- "Character",
- "&EmptyVerySmallSquare"
- ]
- ]
- },
- {
- "input": "▫",
- "description": "Named entity: EmptyVerySmallSquare; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25ab"
- ]
- ]
- },
- {
- "input": "&Eogon",
- "description": "Bad named entity: Eogon without a semi-colon",
- "output": [
- [
- "Character",
- "&Eogon"
- ]
- ]
- },
- {
- "input": "Ę",
- "description": "Named entity: Eogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0118"
- ]
- ]
- },
- {
- "input": "&Eopf",
- "description": "Bad named entity: Eopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Eopf"
- ]
- ]
- },
- {
- "input": "𝔼",
- "description": "Named entity: Eopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd3c"
- ]
- ]
- },
- {
- "input": "&Epsilon",
- "description": "Bad named entity: Epsilon without a semi-colon",
- "output": [
- [
- "Character",
- "&Epsilon"
- ]
- ]
- },
- {
- "input": "Ε",
- "description": "Named entity: Epsilon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0395"
- ]
- ]
- },
- {
- "input": "&Equal",
- "description": "Bad named entity: Equal without a semi-colon",
- "output": [
- [
- "Character",
- "&Equal"
- ]
- ]
- },
- {
- "input": "⩵",
- "description": "Named entity: Equal; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a75"
- ]
- ]
- },
- {
- "input": "&EqualTilde",
- "description": "Bad named entity: EqualTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&EqualTilde"
- ]
- ]
- },
- {
- "input": "≂",
- "description": "Named entity: EqualTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2242"
- ]
- ]
- },
- {
- "input": "&Equilibrium",
- "description": "Bad named entity: Equilibrium without a semi-colon",
- "output": [
- [
- "Character",
- "&Equilibrium"
- ]
- ]
- },
- {
- "input": "⇌",
- "description": "Named entity: Equilibrium; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cc"
- ]
- ]
- },
- {
- "input": "&Escr",
- "description": "Bad named entity: Escr without a semi-colon",
- "output": [
- [
- "Character",
- "&Escr"
- ]
- ]
- },
- {
- "input": "ℰ",
- "description": "Named entity: Escr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2130"
- ]
- ]
- },
- {
- "input": "&Esim",
- "description": "Bad named entity: Esim without a semi-colon",
- "output": [
- [
- "Character",
- "&Esim"
- ]
- ]
- },
- {
- "input": "⩳",
- "description": "Named entity: Esim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a73"
- ]
- ]
- },
- {
- "input": "&Eta",
- "description": "Bad named entity: Eta without a semi-colon",
- "output": [
- [
- "Character",
- "&Eta"
- ]
- ]
- },
- {
- "input": "Η",
- "description": "Named entity: Eta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0397"
- ]
- ]
- },
- {
- "input": "Ë",
- "description": "Named entity: Euml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00cb"
- ]
- ]
- },
- {
- "input": "Ë",
- "description": "Named entity: Euml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00cb"
- ]
- ]
- },
- {
- "input": "&Exists",
- "description": "Bad named entity: Exists without a semi-colon",
- "output": [
- [
- "Character",
- "&Exists"
- ]
- ]
- },
- {
- "input": "∃",
- "description": "Named entity: Exists; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2203"
- ]
- ]
- },
- {
- "input": "&ExponentialE",
- "description": "Bad named entity: ExponentialE without a semi-colon",
- "output": [
- [
- "Character",
- "&ExponentialE"
- ]
- ]
- },
- {
- "input": "ⅇ",
- "description": "Named entity: ExponentialE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2147"
- ]
- ]
- },
- {
- "input": "&Fcy",
- "description": "Bad named entity: Fcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Fcy"
- ]
- ]
- },
- {
- "input": "Ф",
- "description": "Named entity: Fcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0424"
- ]
- ]
- },
- {
- "input": "&Ffr",
- "description": "Bad named entity: Ffr without a semi-colon",
- "output": [
- [
- "Character",
- "&Ffr"
- ]
- ]
- },
- {
- "input": "𝔉",
- "description": "Named entity: Ffr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd09"
- ]
- ]
- },
- {
- "input": "&FilledSmallSquare",
- "description": "Bad named entity: FilledSmallSquare without a semi-colon",
- "output": [
- [
- "Character",
- "&FilledSmallSquare"
- ]
- ]
- },
- {
- "input": "◼",
- "description": "Named entity: FilledSmallSquare; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25fc"
- ]
- ]
- },
- {
- "input": "&FilledVerySmallSquare",
- "description": "Bad named entity: FilledVerySmallSquare without a semi-colon",
- "output": [
- [
- "Character",
- "&FilledVerySmallSquare"
- ]
- ]
- },
- {
- "input": "▪",
- "description": "Named entity: FilledVerySmallSquare; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25aa"
- ]
- ]
- },
- {
- "input": "&Fopf",
- "description": "Bad named entity: Fopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Fopf"
- ]
- ]
- },
- {
- "input": "𝔽",
- "description": "Named entity: Fopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd3d"
- ]
- ]
- },
- {
- "input": "&ForAll",
- "description": "Bad named entity: ForAll without a semi-colon",
- "output": [
- [
- "Character",
- "&ForAll"
- ]
- ]
- },
- {
- "input": "∀",
- "description": "Named entity: ForAll; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2200"
- ]
- ]
- },
- {
- "input": "&Fouriertrf",
- "description": "Bad named entity: Fouriertrf without a semi-colon",
- "output": [
- [
- "Character",
- "&Fouriertrf"
- ]
- ]
- },
- {
- "input": "ℱ",
- "description": "Named entity: Fouriertrf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2131"
- ]
- ]
- },
- {
- "input": "&Fscr",
- "description": "Bad named entity: Fscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Fscr"
- ]
- ]
- },
- {
- "input": "ℱ",
- "description": "Named entity: Fscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2131"
- ]
- ]
- },
- {
- "input": "&GJcy",
- "description": "Bad named entity: GJcy without a semi-colon",
- "output": [
- [
- "Character",
- "&GJcy"
- ]
- ]
- },
- {
- "input": "Ѓ",
- "description": "Named entity: GJcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0403"
- ]
- ]
- },
- {
- "input": ">",
- "description": "Named entity: GT without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- ">"
- ]
- ]
- },
- {
- "input": ">",
- "description": "Named entity: GT; with a semi-colon",
- "output": [
- [
- "Character",
- ">"
- ]
- ]
- },
- {
- "input": "&Gamma",
- "description": "Bad named entity: Gamma without a semi-colon",
- "output": [
- [
- "Character",
- "&Gamma"
- ]
- ]
- },
- {
- "input": "Γ",
- "description": "Named entity: Gamma; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0393"
- ]
- ]
- },
- {
- "input": "&Gammad",
- "description": "Bad named entity: Gammad without a semi-colon",
- "output": [
- [
- "Character",
- "&Gammad"
- ]
- ]
- },
- {
- "input": "Ϝ",
- "description": "Named entity: Gammad; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03dc"
- ]
- ]
- },
- {
- "input": "&Gbreve",
- "description": "Bad named entity: Gbreve without a semi-colon",
- "output": [
- [
- "Character",
- "&Gbreve"
- ]
- ]
- },
- {
- "input": "Ğ",
- "description": "Named entity: Gbreve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u011e"
- ]
- ]
- },
- {
- "input": "&Gcedil",
- "description": "Bad named entity: Gcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&Gcedil"
- ]
- ]
- },
- {
- "input": "Ģ",
- "description": "Named entity: Gcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0122"
- ]
- ]
- },
- {
- "input": "&Gcirc",
- "description": "Bad named entity: Gcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&Gcirc"
- ]
- ]
- },
- {
- "input": "Ĝ",
- "description": "Named entity: Gcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u011c"
- ]
- ]
- },
- {
- "input": "&Gcy",
- "description": "Bad named entity: Gcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Gcy"
- ]
- ]
- },
- {
- "input": "Г",
- "description": "Named entity: Gcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0413"
- ]
- ]
- },
- {
- "input": "&Gdot",
- "description": "Bad named entity: Gdot without a semi-colon",
- "output": [
- [
- "Character",
- "&Gdot"
- ]
- ]
- },
- {
- "input": "Ġ",
- "description": "Named entity: Gdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0120"
- ]
- ]
- },
- {
- "input": "&Gfr",
- "description": "Bad named entity: Gfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Gfr"
- ]
- ]
- },
- {
- "input": "𝔊",
- "description": "Named entity: Gfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd0a"
- ]
- ]
- },
- {
- "input": "&Gg",
- "description": "Bad named entity: Gg without a semi-colon",
- "output": [
- [
- "Character",
- "&Gg"
- ]
- ]
- },
- {
- "input": "⋙",
- "description": "Named entity: Gg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d9"
- ]
- ]
- },
- {
- "input": "&Gopf",
- "description": "Bad named entity: Gopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Gopf"
- ]
- ]
- },
- {
- "input": "𝔾",
- "description": "Named entity: Gopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd3e"
- ]
- ]
- },
- {
- "input": "&GreaterEqual",
- "description": "Bad named entity: GreaterEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&GreaterEqual"
- ]
- ]
- },
- {
- "input": "≥",
- "description": "Named entity: GreaterEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2265"
- ]
- ]
- },
- {
- "input": "&GreaterEqualLess",
- "description": "Bad named entity: GreaterEqualLess without a semi-colon",
- "output": [
- [
- "Character",
- "&GreaterEqualLess"
- ]
- ]
- },
- {
- "input": "⋛",
- "description": "Named entity: GreaterEqualLess; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22db"
- ]
- ]
- },
- {
- "input": "&GreaterFullEqual",
- "description": "Bad named entity: GreaterFullEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&GreaterFullEqual"
- ]
- ]
- },
- {
- "input": "≧",
- "description": "Named entity: GreaterFullEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2267"
- ]
- ]
- },
- {
- "input": "&GreaterGreater",
- "description": "Bad named entity: GreaterGreater without a semi-colon",
- "output": [
- [
- "Character",
- "&GreaterGreater"
- ]
- ]
- },
- {
- "input": "⪢",
- "description": "Named entity: GreaterGreater; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa2"
- ]
- ]
- },
- {
- "input": "&GreaterLess",
- "description": "Bad named entity: GreaterLess without a semi-colon",
- "output": [
- [
- "Character",
- "&GreaterLess"
- ]
- ]
- },
- {
- "input": "≷",
- "description": "Named entity: GreaterLess; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2277"
- ]
- ]
- },
- {
- "input": "&GreaterSlantEqual",
- "description": "Bad named entity: GreaterSlantEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&GreaterSlantEqual"
- ]
- ]
- },
- {
- "input": "⩾",
- "description": "Named entity: GreaterSlantEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7e"
- ]
- ]
- },
- {
- "input": "&GreaterTilde",
- "description": "Bad named entity: GreaterTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&GreaterTilde"
- ]
- ]
- },
- {
- "input": "≳",
- "description": "Named entity: GreaterTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2273"
- ]
- ]
- },
- {
- "input": "&Gscr",
- "description": "Bad named entity: Gscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Gscr"
- ]
- ]
- },
- {
- "input": "𝒢",
- "description": "Named entity: Gscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udca2"
- ]
- ]
- },
- {
- "input": "&Gt",
- "description": "Bad named entity: Gt without a semi-colon",
- "output": [
- [
- "Character",
- "&Gt"
- ]
- ]
- },
- {
- "input": "≫",
- "description": "Named entity: Gt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226b"
- ]
- ]
- },
- {
- "input": "&HARDcy",
- "description": "Bad named entity: HARDcy without a semi-colon",
- "output": [
- [
- "Character",
- "&HARDcy"
- ]
- ]
- },
- {
- "input": "Ъ",
- "description": "Named entity: HARDcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u042a"
- ]
- ]
- },
- {
- "input": "&Hacek",
- "description": "Bad named entity: Hacek without a semi-colon",
- "output": [
- [
- "Character",
- "&Hacek"
- ]
- ]
- },
- {
- "input": "ˇ",
- "description": "Named entity: Hacek; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02c7"
- ]
- ]
- },
- {
- "input": "&Hat",
- "description": "Bad named entity: Hat without a semi-colon",
- "output": [
- [
- "Character",
- "&Hat"
- ]
- ]
- },
- {
- "input": "^",
- "description": "Named entity: Hat; with a semi-colon",
- "output": [
- [
- "Character",
- "^"
- ]
- ]
- },
- {
- "input": "&Hcirc",
- "description": "Bad named entity: Hcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&Hcirc"
- ]
- ]
- },
- {
- "input": "Ĥ",
- "description": "Named entity: Hcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0124"
- ]
- ]
- },
- {
- "input": "&Hfr",
- "description": "Bad named entity: Hfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Hfr"
- ]
- ]
- },
- {
- "input": "ℌ",
- "description": "Named entity: Hfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210c"
- ]
- ]
- },
- {
- "input": "&HilbertSpace",
- "description": "Bad named entity: HilbertSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&HilbertSpace"
- ]
- ]
- },
- {
- "input": "ℋ",
- "description": "Named entity: HilbertSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210b"
- ]
- ]
- },
- {
- "input": "&Hopf",
- "description": "Bad named entity: Hopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Hopf"
- ]
- ]
- },
- {
- "input": "ℍ",
- "description": "Named entity: Hopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210d"
- ]
- ]
- },
- {
- "input": "&HorizontalLine",
- "description": "Bad named entity: HorizontalLine without a semi-colon",
- "output": [
- [
- "Character",
- "&HorizontalLine"
- ]
- ]
- },
- {
- "input": "─",
- "description": "Named entity: HorizontalLine; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2500"
- ]
- ]
- },
- {
- "input": "&Hscr",
- "description": "Bad named entity: Hscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Hscr"
- ]
- ]
- },
- {
- "input": "ℋ",
- "description": "Named entity: Hscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210b"
- ]
- ]
- },
- {
- "input": "&Hstrok",
- "description": "Bad named entity: Hstrok without a semi-colon",
- "output": [
- [
- "Character",
- "&Hstrok"
- ]
- ]
- },
- {
- "input": "Ħ",
- "description": "Named entity: Hstrok; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0126"
- ]
- ]
- },
- {
- "input": "&HumpDownHump",
- "description": "Bad named entity: HumpDownHump without a semi-colon",
- "output": [
- [
- "Character",
- "&HumpDownHump"
- ]
- ]
- },
- {
- "input": "≎",
- "description": "Named entity: HumpDownHump; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224e"
- ]
- ]
- },
- {
- "input": "&HumpEqual",
- "description": "Bad named entity: HumpEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&HumpEqual"
- ]
- ]
- },
- {
- "input": "≏",
- "description": "Named entity: HumpEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224f"
- ]
- ]
- },
- {
- "input": "&IEcy",
- "description": "Bad named entity: IEcy without a semi-colon",
- "output": [
- [
- "Character",
- "&IEcy"
- ]
- ]
- },
- {
- "input": "Е",
- "description": "Named entity: IEcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0415"
- ]
- ]
- },
- {
- "input": "&IJlig",
- "description": "Bad named entity: IJlig without a semi-colon",
- "output": [
- [
- "Character",
- "&IJlig"
- ]
- ]
- },
- {
- "input": "IJ",
- "description": "Named entity: IJlig; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0132"
- ]
- ]
- },
- {
- "input": "&IOcy",
- "description": "Bad named entity: IOcy without a semi-colon",
- "output": [
- [
- "Character",
- "&IOcy"
- ]
- ]
- },
- {
- "input": "Ё",
- "description": "Named entity: IOcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0401"
- ]
- ]
- },
- {
- "input": "Í",
- "description": "Named entity: Iacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00cd"
- ]
- ]
- },
- {
- "input": "Í",
- "description": "Named entity: Iacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00cd"
- ]
- ]
- },
- {
- "input": "Î",
- "description": "Named entity: Icirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ce"
- ]
- ]
- },
- {
- "input": "Î",
- "description": "Named entity: Icirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ce"
- ]
- ]
- },
- {
- "input": "&Icy",
- "description": "Bad named entity: Icy without a semi-colon",
- "output": [
- [
- "Character",
- "&Icy"
- ]
- ]
- },
- {
- "input": "И",
- "description": "Named entity: Icy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0418"
- ]
- ]
- },
- {
- "input": "&Idot",
- "description": "Bad named entity: Idot without a semi-colon",
- "output": [
- [
- "Character",
- "&Idot"
- ]
- ]
- },
- {
- "input": "İ",
- "description": "Named entity: Idot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0130"
- ]
- ]
- },
- {
- "input": "&Ifr",
- "description": "Bad named entity: Ifr without a semi-colon",
- "output": [
- [
- "Character",
- "&Ifr"
- ]
- ]
- },
- {
- "input": "ℑ",
- "description": "Named entity: Ifr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2111"
- ]
- ]
- },
- {
- "input": "Ì",
- "description": "Named entity: Igrave without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00cc"
- ]
- ]
- },
- {
- "input": "Ì",
- "description": "Named entity: Igrave; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00cc"
- ]
- ]
- },
- {
- "input": "&Im",
- "description": "Bad named entity: Im without a semi-colon",
- "output": [
- [
- "Character",
- "&Im"
- ]
- ]
- },
- {
- "input": "ℑ",
- "description": "Named entity: Im; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2111"
- ]
- ]
- },
- {
- "input": "&Imacr",
- "description": "Bad named entity: Imacr without a semi-colon",
- "output": [
- [
- "Character",
- "&Imacr"
- ]
- ]
- },
- {
- "input": "Ī",
- "description": "Named entity: Imacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u012a"
- ]
- ]
- },
- {
- "input": "&ImaginaryI",
- "description": "Bad named entity: ImaginaryI without a semi-colon",
- "output": [
- [
- "Character",
- "&ImaginaryI"
- ]
- ]
- },
- {
- "input": "ⅈ",
- "description": "Named entity: ImaginaryI; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2148"
- ]
- ]
- },
- {
- "input": "&Implies",
- "description": "Bad named entity: Implies without a semi-colon",
- "output": [
- [
- "Character",
- "&Implies"
- ]
- ]
- },
- {
- "input": "⇒",
- "description": "Named entity: Implies; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d2"
- ]
- ]
- },
- {
- "input": "&Int",
- "description": "Bad named entity: Int without a semi-colon",
- "output": [
- [
- "Character",
- "&Int"
- ]
- ]
- },
- {
- "input": "∬",
- "description": "Named entity: Int; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222c"
- ]
- ]
- },
- {
- "input": "&Integral",
- "description": "Bad named entity: Integral without a semi-colon",
- "output": [
- [
- "Character",
- "&Integral"
- ]
- ]
- },
- {
- "input": "∫",
- "description": "Named entity: Integral; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222b"
- ]
- ]
- },
- {
- "input": "&Intersection",
- "description": "Bad named entity: Intersection without a semi-colon",
- "output": [
- [
- "Character",
- "&Intersection"
- ]
- ]
- },
- {
- "input": "⋂",
- "description": "Named entity: Intersection; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c2"
- ]
- ]
- },
- {
- "input": "&InvisibleComma",
- "description": "Bad named entity: InvisibleComma without a semi-colon",
- "output": [
- [
- "Character",
- "&InvisibleComma"
- ]
- ]
- },
- {
- "input": "⁣",
- "description": "Named entity: InvisibleComma; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2063"
- ]
- ]
- },
- {
- "input": "&InvisibleTimes",
- "description": "Bad named entity: InvisibleTimes without a semi-colon",
- "output": [
- [
- "Character",
- "&InvisibleTimes"
- ]
- ]
- },
- {
- "input": "⁢",
- "description": "Named entity: InvisibleTimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2062"
- ]
- ]
- },
- {
- "input": "&Iogon",
- "description": "Bad named entity: Iogon without a semi-colon",
- "output": [
- [
- "Character",
- "&Iogon"
- ]
- ]
- },
- {
- "input": "Į",
- "description": "Named entity: Iogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u012e"
- ]
- ]
- },
- {
- "input": "&Iopf",
- "description": "Bad named entity: Iopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Iopf"
- ]
- ]
- },
- {
- "input": "𝕀",
- "description": "Named entity: Iopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd40"
- ]
- ]
- },
- {
- "input": "&Iota",
- "description": "Bad named entity: Iota without a semi-colon",
- "output": [
- [
- "Character",
- "&Iota"
- ]
- ]
- },
- {
- "input": "Ι",
- "description": "Named entity: Iota; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0399"
- ]
- ]
- },
- {
- "input": "&Iscr",
- "description": "Bad named entity: Iscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Iscr"
- ]
- ]
- },
- {
- "input": "ℐ",
- "description": "Named entity: Iscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2110"
- ]
- ]
- },
- {
- "input": "&Itilde",
- "description": "Bad named entity: Itilde without a semi-colon",
- "output": [
- [
- "Character",
- "&Itilde"
- ]
- ]
- },
- {
- "input": "Ĩ",
- "description": "Named entity: Itilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0128"
- ]
- ]
- },
- {
- "input": "&Iukcy",
- "description": "Bad named entity: Iukcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Iukcy"
- ]
- ]
- },
- {
- "input": "І",
- "description": "Named entity: Iukcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0406"
- ]
- ]
- },
- {
- "input": "Ï",
- "description": "Named entity: Iuml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00cf"
- ]
- ]
- },
- {
- "input": "Ï",
- "description": "Named entity: Iuml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00cf"
- ]
- ]
- },
- {
- "input": "&Jcirc",
- "description": "Bad named entity: Jcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&Jcirc"
- ]
- ]
- },
- {
- "input": "Ĵ",
- "description": "Named entity: Jcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0134"
- ]
- ]
- },
- {
- "input": "&Jcy",
- "description": "Bad named entity: Jcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Jcy"
- ]
- ]
- },
- {
- "input": "Й",
- "description": "Named entity: Jcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0419"
- ]
- ]
- },
- {
- "input": "&Jfr",
- "description": "Bad named entity: Jfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Jfr"
- ]
- ]
- },
- {
- "input": "𝔍",
- "description": "Named entity: Jfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd0d"
- ]
- ]
- },
- {
- "input": "&Jopf",
- "description": "Bad named entity: Jopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Jopf"
- ]
- ]
- },
- {
- "input": "𝕁",
- "description": "Named entity: Jopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd41"
- ]
- ]
- },
- {
- "input": "&Jscr",
- "description": "Bad named entity: Jscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Jscr"
- ]
- ]
- },
- {
- "input": "𝒥",
- "description": "Named entity: Jscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udca5"
- ]
- ]
- },
- {
- "input": "&Jsercy",
- "description": "Bad named entity: Jsercy without a semi-colon",
- "output": [
- [
- "Character",
- "&Jsercy"
- ]
- ]
- },
- {
- "input": "Ј",
- "description": "Named entity: Jsercy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0408"
- ]
- ]
- },
- {
- "input": "&Jukcy",
- "description": "Bad named entity: Jukcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Jukcy"
- ]
- ]
- },
- {
- "input": "Є",
- "description": "Named entity: Jukcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0404"
- ]
- ]
- },
- {
- "input": "&KHcy",
- "description": "Bad named entity: KHcy without a semi-colon",
- "output": [
- [
- "Character",
- "&KHcy"
- ]
- ]
- },
- {
- "input": "Х",
- "description": "Named entity: KHcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0425"
- ]
- ]
- },
- {
- "input": "&KJcy",
- "description": "Bad named entity: KJcy without a semi-colon",
- "output": [
- [
- "Character",
- "&KJcy"
- ]
- ]
- },
- {
- "input": "Ќ",
- "description": "Named entity: KJcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u040c"
- ]
- ]
- },
- {
- "input": "&Kappa",
- "description": "Bad named entity: Kappa without a semi-colon",
- "output": [
- [
- "Character",
- "&Kappa"
- ]
- ]
- },
- {
- "input": "Κ",
- "description": "Named entity: Kappa; with a semi-colon",
- "output": [
- [
- "Character",
- "\u039a"
- ]
- ]
- },
- {
- "input": "&Kcedil",
- "description": "Bad named entity: Kcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&Kcedil"
- ]
- ]
- },
- {
- "input": "Ķ",
- "description": "Named entity: Kcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0136"
- ]
- ]
- },
- {
- "input": "&Kcy",
- "description": "Bad named entity: Kcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Kcy"
- ]
- ]
- },
- {
- "input": "К",
- "description": "Named entity: Kcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u041a"
- ]
- ]
- },
- {
- "input": "&Kfr",
- "description": "Bad named entity: Kfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Kfr"
- ]
- ]
- },
- {
- "input": "𝔎",
- "description": "Named entity: Kfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd0e"
- ]
- ]
- },
- {
- "input": "&Kopf",
- "description": "Bad named entity: Kopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Kopf"
- ]
- ]
- },
- {
- "input": "𝕂",
- "description": "Named entity: Kopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd42"
- ]
- ]
- },
- {
- "input": "&Kscr",
- "description": "Bad named entity: Kscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Kscr"
- ]
- ]
- },
- {
- "input": "𝒦",
- "description": "Named entity: Kscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udca6"
- ]
- ]
- },
- {
- "input": "&LJcy",
- "description": "Bad named entity: LJcy without a semi-colon",
- "output": [
- [
- "Character",
- "&LJcy"
- ]
- ]
- },
- {
- "input": "Љ",
- "description": "Named entity: LJcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0409"
- ]
- ]
- },
- {
- "input": "<",
- "description": "Named entity: LT without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "<"
- ]
- ]
- },
- {
- "input": "<",
- "description": "Named entity: LT; with a semi-colon",
- "output": [
- [
- "Character",
- "<"
- ]
- ]
- },
- {
- "input": "&Lacute",
- "description": "Bad named entity: Lacute without a semi-colon",
- "output": [
- [
- "Character",
- "&Lacute"
- ]
- ]
- },
- {
- "input": "Ĺ",
- "description": "Named entity: Lacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0139"
- ]
- ]
- },
- {
- "input": "&Lambda",
- "description": "Bad named entity: Lambda without a semi-colon",
- "output": [
- [
- "Character",
- "&Lambda"
- ]
- ]
- },
- {
- "input": "Λ",
- "description": "Named entity: Lambda; with a semi-colon",
- "output": [
- [
- "Character",
- "\u039b"
- ]
- ]
- },
- {
- "input": "&Lang",
- "description": "Bad named entity: Lang without a semi-colon",
- "output": [
- [
- "Character",
- "&Lang"
- ]
- ]
- },
- {
- "input": "⟪",
- "description": "Named entity: Lang; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27ea"
- ]
- ]
- },
- {
- "input": "&Laplacetrf",
- "description": "Bad named entity: Laplacetrf without a semi-colon",
- "output": [
- [
- "Character",
- "&Laplacetrf"
- ]
- ]
- },
- {
- "input": "ℒ",
- "description": "Named entity: Laplacetrf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2112"
- ]
- ]
- },
- {
- "input": "&Larr",
- "description": "Bad named entity: Larr without a semi-colon",
- "output": [
- [
- "Character",
- "&Larr"
- ]
- ]
- },
- {
- "input": "↞",
- "description": "Named entity: Larr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219e"
- ]
- ]
- },
- {
- "input": "&Lcaron",
- "description": "Bad named entity: Lcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Lcaron"
- ]
- ]
- },
- {
- "input": "Ľ",
- "description": "Named entity: Lcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u013d"
- ]
- ]
- },
- {
- "input": "&Lcedil",
- "description": "Bad named entity: Lcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&Lcedil"
- ]
- ]
- },
- {
- "input": "Ļ",
- "description": "Named entity: Lcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u013b"
- ]
- ]
- },
- {
- "input": "&Lcy",
- "description": "Bad named entity: Lcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Lcy"
- ]
- ]
- },
- {
- "input": "Л",
- "description": "Named entity: Lcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u041b"
- ]
- ]
- },
- {
- "input": "&LeftAngleBracket",
- "description": "Bad named entity: LeftAngleBracket without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftAngleBracket"
- ]
- ]
- },
- {
- "input": "⟨",
- "description": "Named entity: LeftAngleBracket; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e8"
- ]
- ]
- },
- {
- "input": "&LeftArrow",
- "description": "Bad named entity: LeftArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftArrow"
- ]
- ]
- },
- {
- "input": "←",
- "description": "Named entity: LeftArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2190"
- ]
- ]
- },
- {
- "input": "&LeftArrowBar",
- "description": "Bad named entity: LeftArrowBar without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftArrowBar"
- ]
- ]
- },
- {
- "input": "⇤",
- "description": "Named entity: LeftArrowBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21e4"
- ]
- ]
- },
- {
- "input": "&LeftArrowRightArrow",
- "description": "Bad named entity: LeftArrowRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftArrowRightArrow"
- ]
- ]
- },
- {
- "input": "⇆",
- "description": "Named entity: LeftArrowRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c6"
- ]
- ]
- },
- {
- "input": "&LeftCeiling",
- "description": "Bad named entity: LeftCeiling without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftCeiling"
- ]
- ]
- },
- {
- "input": "⌈",
- "description": "Named entity: LeftCeiling; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2308"
- ]
- ]
- },
- {
- "input": "&LeftDoubleBracket",
- "description": "Bad named entity: LeftDoubleBracket without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftDoubleBracket"
- ]
- ]
- },
- {
- "input": "⟦",
- "description": "Named entity: LeftDoubleBracket; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e6"
- ]
- ]
- },
- {
- "input": "&LeftDownTeeVector",
- "description": "Bad named entity: LeftDownTeeVector without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftDownTeeVector"
- ]
- ]
- },
- {
- "input": "⥡",
- "description": "Named entity: LeftDownTeeVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2961"
- ]
- ]
- },
- {
- "input": "&LeftDownVector",
- "description": "Bad named entity: LeftDownVector without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftDownVector"
- ]
- ]
- },
- {
- "input": "⇃",
- "description": "Named entity: LeftDownVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c3"
- ]
- ]
- },
- {
- "input": "&LeftDownVectorBar",
- "description": "Bad named entity: LeftDownVectorBar without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftDownVectorBar"
- ]
- ]
- },
- {
- "input": "⥙",
- "description": "Named entity: LeftDownVectorBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2959"
- ]
- ]
- },
- {
- "input": "&LeftFloor",
- "description": "Bad named entity: LeftFloor without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftFloor"
- ]
- ]
- },
- {
- "input": "⌊",
- "description": "Named entity: LeftFloor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u230a"
- ]
- ]
- },
- {
- "input": "&LeftRightArrow",
- "description": "Bad named entity: LeftRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftRightArrow"
- ]
- ]
- },
- {
- "input": "↔",
- "description": "Named entity: LeftRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2194"
- ]
- ]
- },
- {
- "input": "&LeftRightVector",
- "description": "Bad named entity: LeftRightVector without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftRightVector"
- ]
- ]
- },
- {
- "input": "⥎",
- "description": "Named entity: LeftRightVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u294e"
- ]
- ]
- },
- {
- "input": "&LeftTee",
- "description": "Bad named entity: LeftTee without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftTee"
- ]
- ]
- },
- {
- "input": "⊣",
- "description": "Named entity: LeftTee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a3"
- ]
- ]
- },
- {
- "input": "&LeftTeeArrow",
- "description": "Bad named entity: LeftTeeArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftTeeArrow"
- ]
- ]
- },
- {
- "input": "↤",
- "description": "Named entity: LeftTeeArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a4"
- ]
- ]
- },
- {
- "input": "&LeftTeeVector",
- "description": "Bad named entity: LeftTeeVector without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftTeeVector"
- ]
- ]
- },
- {
- "input": "⥚",
- "description": "Named entity: LeftTeeVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u295a"
- ]
- ]
- },
- {
- "input": "&LeftTriangle",
- "description": "Bad named entity: LeftTriangle without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftTriangle"
- ]
- ]
- },
- {
- "input": "⊲",
- "description": "Named entity: LeftTriangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b2"
- ]
- ]
- },
- {
- "input": "&LeftTriangleBar",
- "description": "Bad named entity: LeftTriangleBar without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftTriangleBar"
- ]
- ]
- },
- {
- "input": "⧏",
- "description": "Named entity: LeftTriangleBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29cf"
- ]
- ]
- },
- {
- "input": "&LeftTriangleEqual",
- "description": "Bad named entity: LeftTriangleEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftTriangleEqual"
- ]
- ]
- },
- {
- "input": "⊴",
- "description": "Named entity: LeftTriangleEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b4"
- ]
- ]
- },
- {
- "input": "&LeftUpDownVector",
- "description": "Bad named entity: LeftUpDownVector without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftUpDownVector"
- ]
- ]
- },
- {
- "input": "⥑",
- "description": "Named entity: LeftUpDownVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2951"
- ]
- ]
- },
- {
- "input": "&LeftUpTeeVector",
- "description": "Bad named entity: LeftUpTeeVector without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftUpTeeVector"
- ]
- ]
- },
- {
- "input": "⥠",
- "description": "Named entity: LeftUpTeeVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2960"
- ]
- ]
- },
- {
- "input": "&LeftUpVector",
- "description": "Bad named entity: LeftUpVector without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftUpVector"
- ]
- ]
- },
- {
- "input": "↿",
- "description": "Named entity: LeftUpVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bf"
- ]
- ]
- },
- {
- "input": "&LeftUpVectorBar",
- "description": "Bad named entity: LeftUpVectorBar without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftUpVectorBar"
- ]
- ]
- },
- {
- "input": "⥘",
- "description": "Named entity: LeftUpVectorBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2958"
- ]
- ]
- },
- {
- "input": "&LeftVector",
- "description": "Bad named entity: LeftVector without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftVector"
- ]
- ]
- },
- {
- "input": "↼",
- "description": "Named entity: LeftVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bc"
- ]
- ]
- },
- {
- "input": "&LeftVectorBar",
- "description": "Bad named entity: LeftVectorBar without a semi-colon",
- "output": [
- [
- "Character",
- "&LeftVectorBar"
- ]
- ]
- },
- {
- "input": "⥒",
- "description": "Named entity: LeftVectorBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2952"
- ]
- ]
- },
- {
- "input": "&Leftarrow",
- "description": "Bad named entity: Leftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Leftarrow"
- ]
- ]
- },
- {
- "input": "⇐",
- "description": "Named entity: Leftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d0"
- ]
- ]
- },
- {
- "input": "&Leftrightarrow",
- "description": "Bad named entity: Leftrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Leftrightarrow"
- ]
- ]
- },
- {
- "input": "⇔",
- "description": "Named entity: Leftrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d4"
- ]
- ]
- },
- {
- "input": "&LessEqualGreater",
- "description": "Bad named entity: LessEqualGreater without a semi-colon",
- "output": [
- [
- "Character",
- "&LessEqualGreater"
- ]
- ]
- },
- {
- "input": "⋚",
- "description": "Named entity: LessEqualGreater; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22da"
- ]
- ]
- },
- {
- "input": "&LessFullEqual",
- "description": "Bad named entity: LessFullEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&LessFullEqual"
- ]
- ]
- },
- {
- "input": "≦",
- "description": "Named entity: LessFullEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2266"
- ]
- ]
- },
- {
- "input": "&LessGreater",
- "description": "Bad named entity: LessGreater without a semi-colon",
- "output": [
- [
- "Character",
- "&LessGreater"
- ]
- ]
- },
- {
- "input": "≶",
- "description": "Named entity: LessGreater; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2276"
- ]
- ]
- },
- {
- "input": "&LessLess",
- "description": "Bad named entity: LessLess without a semi-colon",
- "output": [
- [
- "Character",
- "&LessLess"
- ]
- ]
- },
- {
- "input": "⪡",
- "description": "Named entity: LessLess; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa1"
- ]
- ]
- },
- {
- "input": "&LessSlantEqual",
- "description": "Bad named entity: LessSlantEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&LessSlantEqual"
- ]
- ]
- },
- {
- "input": "⩽",
- "description": "Named entity: LessSlantEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7d"
- ]
- ]
- },
- {
- "input": "&LessTilde",
- "description": "Bad named entity: LessTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&LessTilde"
- ]
- ]
- },
- {
- "input": "≲",
- "description": "Named entity: LessTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2272"
- ]
- ]
- },
- {
- "input": "&Lfr",
- "description": "Bad named entity: Lfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Lfr"
- ]
- ]
- },
- {
- "input": "𝔏",
- "description": "Named entity: Lfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd0f"
- ]
- ]
- },
- {
- "input": "&Ll",
- "description": "Bad named entity: Ll without a semi-colon",
- "output": [
- [
- "Character",
- "&Ll"
- ]
- ]
- },
- {
- "input": "⋘",
- "description": "Named entity: Ll; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d8"
- ]
- ]
- },
- {
- "input": "&Lleftarrow",
- "description": "Bad named entity: Lleftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Lleftarrow"
- ]
- ]
- },
- {
- "input": "⇚",
- "description": "Named entity: Lleftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21da"
- ]
- ]
- },
- {
- "input": "&Lmidot",
- "description": "Bad named entity: Lmidot without a semi-colon",
- "output": [
- [
- "Character",
- "&Lmidot"
- ]
- ]
- },
- {
- "input": "Ŀ",
- "description": "Named entity: Lmidot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u013f"
- ]
- ]
- },
- {
- "input": "&LongLeftArrow",
- "description": "Bad named entity: LongLeftArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LongLeftArrow"
- ]
- ]
- },
- {
- "input": "⟵",
- "description": "Named entity: LongLeftArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f5"
- ]
- ]
- },
- {
- "input": "&LongLeftRightArrow",
- "description": "Bad named entity: LongLeftRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LongLeftRightArrow"
- ]
- ]
- },
- {
- "input": "⟷",
- "description": "Named entity: LongLeftRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f7"
- ]
- ]
- },
- {
- "input": "&LongRightArrow",
- "description": "Bad named entity: LongRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LongRightArrow"
- ]
- ]
- },
- {
- "input": "⟶",
- "description": "Named entity: LongRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f6"
- ]
- ]
- },
- {
- "input": "&Longleftarrow",
- "description": "Bad named entity: Longleftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Longleftarrow"
- ]
- ]
- },
- {
- "input": "⟸",
- "description": "Named entity: Longleftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f8"
- ]
- ]
- },
- {
- "input": "&Longleftrightarrow",
- "description": "Bad named entity: Longleftrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Longleftrightarrow"
- ]
- ]
- },
- {
- "input": "⟺",
- "description": "Named entity: Longleftrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27fa"
- ]
- ]
- },
- {
- "input": "&Longrightarrow",
- "description": "Bad named entity: Longrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Longrightarrow"
- ]
- ]
- },
- {
- "input": "⟹",
- "description": "Named entity: Longrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f9"
- ]
- ]
- },
- {
- "input": "&Lopf",
- "description": "Bad named entity: Lopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Lopf"
- ]
- ]
- },
- {
- "input": "𝕃",
- "description": "Named entity: Lopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd43"
- ]
- ]
- },
- {
- "input": "&LowerLeftArrow",
- "description": "Bad named entity: LowerLeftArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LowerLeftArrow"
- ]
- ]
- },
- {
- "input": "↙",
- "description": "Named entity: LowerLeftArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2199"
- ]
- ]
- },
- {
- "input": "&LowerRightArrow",
- "description": "Bad named entity: LowerRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&LowerRightArrow"
- ]
- ]
- },
- {
- "input": "↘",
- "description": "Named entity: LowerRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2198"
- ]
- ]
- },
- {
- "input": "&Lscr",
- "description": "Bad named entity: Lscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Lscr"
- ]
- ]
- },
- {
- "input": "ℒ",
- "description": "Named entity: Lscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2112"
- ]
- ]
- },
- {
- "input": "&Lsh",
- "description": "Bad named entity: Lsh without a semi-colon",
- "output": [
- [
- "Character",
- "&Lsh"
- ]
- ]
- },
- {
- "input": "↰",
- "description": "Named entity: Lsh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b0"
- ]
- ]
- },
- {
- "input": "&Lstrok",
- "description": "Bad named entity: Lstrok without a semi-colon",
- "output": [
- [
- "Character",
- "&Lstrok"
- ]
- ]
- },
- {
- "input": "Ł",
- "description": "Named entity: Lstrok; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0141"
- ]
- ]
- },
- {
- "input": "&Lt",
- "description": "Bad named entity: Lt without a semi-colon",
- "output": [
- [
- "Character",
- "&Lt"
- ]
- ]
- },
- {
- "input": "≪",
- "description": "Named entity: Lt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226a"
- ]
- ]
- },
- {
- "input": "&Map",
- "description": "Bad named entity: Map without a semi-colon",
- "output": [
- [
- "Character",
- "&Map"
- ]
- ]
- },
- {
- "input": "⤅",
- "description": "Named entity: Map; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2905"
- ]
- ]
- },
- {
- "input": "&Mcy",
- "description": "Bad named entity: Mcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Mcy"
- ]
- ]
- },
- {
- "input": "М",
- "description": "Named entity: Mcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u041c"
- ]
- ]
- },
- {
- "input": "&MediumSpace",
- "description": "Bad named entity: MediumSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&MediumSpace"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: MediumSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u205f"
- ]
- ]
- },
- {
- "input": "&Mellintrf",
- "description": "Bad named entity: Mellintrf without a semi-colon",
- "output": [
- [
- "Character",
- "&Mellintrf"
- ]
- ]
- },
- {
- "input": "ℳ",
- "description": "Named entity: Mellintrf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2133"
- ]
- ]
- },
- {
- "input": "&Mfr",
- "description": "Bad named entity: Mfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Mfr"
- ]
- ]
- },
- {
- "input": "𝔐",
- "description": "Named entity: Mfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd10"
- ]
- ]
- },
- {
- "input": "&MinusPlus",
- "description": "Bad named entity: MinusPlus without a semi-colon",
- "output": [
- [
- "Character",
- "&MinusPlus"
- ]
- ]
- },
- {
- "input": "∓",
- "description": "Named entity: MinusPlus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2213"
- ]
- ]
- },
- {
- "input": "&Mopf",
- "description": "Bad named entity: Mopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Mopf"
- ]
- ]
- },
- {
- "input": "𝕄",
- "description": "Named entity: Mopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd44"
- ]
- ]
- },
- {
- "input": "&Mscr",
- "description": "Bad named entity: Mscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Mscr"
- ]
- ]
- },
- {
- "input": "ℳ",
- "description": "Named entity: Mscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2133"
- ]
- ]
- },
- {
- "input": "&Mu",
- "description": "Bad named entity: Mu without a semi-colon",
- "output": [
- [
- "Character",
- "&Mu"
- ]
- ]
- },
- {
- "input": "Μ",
- "description": "Named entity: Mu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u039c"
- ]
- ]
- },
- {
- "input": "&NJcy",
- "description": "Bad named entity: NJcy without a semi-colon",
- "output": [
- [
- "Character",
- "&NJcy"
- ]
- ]
- },
- {
- "input": "Њ",
- "description": "Named entity: NJcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u040a"
- ]
- ]
- },
- {
- "input": "&Nacute",
- "description": "Bad named entity: Nacute without a semi-colon",
- "output": [
- [
- "Character",
- "&Nacute"
- ]
- ]
- },
- {
- "input": "Ń",
- "description": "Named entity: Nacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0143"
- ]
- ]
- },
- {
- "input": "&Ncaron",
- "description": "Bad named entity: Ncaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Ncaron"
- ]
- ]
- },
- {
- "input": "Ň",
- "description": "Named entity: Ncaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0147"
- ]
- ]
- },
- {
- "input": "&Ncedil",
- "description": "Bad named entity: Ncedil without a semi-colon",
- "output": [
- [
- "Character",
- "&Ncedil"
- ]
- ]
- },
- {
- "input": "Ņ",
- "description": "Named entity: Ncedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0145"
- ]
- ]
- },
- {
- "input": "&Ncy",
- "description": "Bad named entity: Ncy without a semi-colon",
- "output": [
- [
- "Character",
- "&Ncy"
- ]
- ]
- },
- {
- "input": "Н",
- "description": "Named entity: Ncy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u041d"
- ]
- ]
- },
- {
- "input": "&NegativeMediumSpace",
- "description": "Bad named entity: NegativeMediumSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&NegativeMediumSpace"
- ]
- ]
- },
- {
- "input": "​",
- "description": "Named entity: NegativeMediumSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200b"
- ]
- ]
- },
- {
- "input": "&NegativeThickSpace",
- "description": "Bad named entity: NegativeThickSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&NegativeThickSpace"
- ]
- ]
- },
- {
- "input": "​",
- "description": "Named entity: NegativeThickSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200b"
- ]
- ]
- },
- {
- "input": "&NegativeThinSpace",
- "description": "Bad named entity: NegativeThinSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&NegativeThinSpace"
- ]
- ]
- },
- {
- "input": "​",
- "description": "Named entity: NegativeThinSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200b"
- ]
- ]
- },
- {
- "input": "&NegativeVeryThinSpace",
- "description": "Bad named entity: NegativeVeryThinSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&NegativeVeryThinSpace"
- ]
- ]
- },
- {
- "input": "​",
- "description": "Named entity: NegativeVeryThinSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200b"
- ]
- ]
- },
- {
- "input": "&NestedGreaterGreater",
- "description": "Bad named entity: NestedGreaterGreater without a semi-colon",
- "output": [
- [
- "Character",
- "&NestedGreaterGreater"
- ]
- ]
- },
- {
- "input": "≫",
- "description": "Named entity: NestedGreaterGreater; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226b"
- ]
- ]
- },
- {
- "input": "&NestedLessLess",
- "description": "Bad named entity: NestedLessLess without a semi-colon",
- "output": [
- [
- "Character",
- "&NestedLessLess"
- ]
- ]
- },
- {
- "input": "≪",
- "description": "Named entity: NestedLessLess; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226a"
- ]
- ]
- },
- {
- "input": "&NewLine",
- "description": "Bad named entity: NewLine without a semi-colon",
- "output": [
- [
- "Character",
- "&NewLine"
- ]
- ]
- },
- {
- "input": "
",
- "description": "Named entity: NewLine; with a semi-colon",
- "output": [
- [
- "Character",
- "\n"
- ]
- ]
- },
- {
- "input": "&Nfr",
- "description": "Bad named entity: Nfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Nfr"
- ]
- ]
- },
- {
- "input": "𝔑",
- "description": "Named entity: Nfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd11"
- ]
- ]
- },
- {
- "input": "&NoBreak",
- "description": "Bad named entity: NoBreak without a semi-colon",
- "output": [
- [
- "Character",
- "&NoBreak"
- ]
- ]
- },
- {
- "input": "⁠",
- "description": "Named entity: NoBreak; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2060"
- ]
- ]
- },
- {
- "input": "&NonBreakingSpace",
- "description": "Bad named entity: NonBreakingSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&NonBreakingSpace"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: NonBreakingSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a0"
- ]
- ]
- },
- {
- "input": "&Nopf",
- "description": "Bad named entity: Nopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Nopf"
- ]
- ]
- },
- {
- "input": "ℕ",
- "description": "Named entity: Nopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2115"
- ]
- ]
- },
- {
- "input": "&Not",
- "description": "Bad named entity: Not without a semi-colon",
- "output": [
- [
- "Character",
- "&Not"
- ]
- ]
- },
- {
- "input": "⫬",
- "description": "Named entity: Not; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aec"
- ]
- ]
- },
- {
- "input": "&NotCongruent",
- "description": "Bad named entity: NotCongruent without a semi-colon",
- "output": [
- [
- "Character",
- "&NotCongruent"
- ]
- ]
- },
- {
- "input": "≢",
- "description": "Named entity: NotCongruent; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2262"
- ]
- ]
- },
- {
- "input": "&NotCupCap",
- "description": "Bad named entity: NotCupCap without a semi-colon",
- "output": [
- [
- "Character",
- "&NotCupCap"
- ]
- ]
- },
- {
- "input": "≭",
- "description": "Named entity: NotCupCap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226d"
- ]
- ]
- },
- {
- "input": "&NotDoubleVerticalBar",
- "description": "Bad named entity: NotDoubleVerticalBar without a semi-colon",
- "output": [
- [
- "Character",
- "&NotDoubleVerticalBar"
- ]
- ]
- },
- {
- "input": "∦",
- "description": "Named entity: NotDoubleVerticalBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2226"
- ]
- ]
- },
- {
- "input": "&NotElement",
- "description": "Bad named entity: NotElement without a semi-colon",
- "output": [
- [
- "Character",
- "&NotElement"
- ]
- ]
- },
- {
- "input": "∉",
- "description": "Named entity: NotElement; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2209"
- ]
- ]
- },
- {
- "input": "&NotEqual",
- "description": "Bad named entity: NotEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotEqual"
- ]
- ]
- },
- {
- "input": "≠",
- "description": "Named entity: NotEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2260"
- ]
- ]
- },
- {
- "input": "&NotEqualTilde",
- "description": "Bad named entity: NotEqualTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&NotEqualTilde"
- ]
- ]
- },
- {
- "input": "≂̸",
- "description": "Named entity: NotEqualTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2242\u0338"
- ]
- ]
- },
- {
- "input": "&NotExists",
- "description": "Bad named entity: NotExists without a semi-colon",
- "output": [
- [
- "Character",
- "&NotExists"
- ]
- ]
- },
- {
- "input": "∄",
- "description": "Named entity: NotExists; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2204"
- ]
- ]
- },
- {
- "input": "&NotGreater",
- "description": "Bad named entity: NotGreater without a semi-colon",
- "output": [
- [
- "Character",
- "&NotGreater"
- ]
- ]
- },
- {
- "input": "≯",
- "description": "Named entity: NotGreater; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226f"
- ]
- ]
- },
- {
- "input": "&NotGreaterEqual",
- "description": "Bad named entity: NotGreaterEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotGreaterEqual"
- ]
- ]
- },
- {
- "input": "≱",
- "description": "Named entity: NotGreaterEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2271"
- ]
- ]
- },
- {
- "input": "&NotGreaterFullEqual",
- "description": "Bad named entity: NotGreaterFullEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotGreaterFullEqual"
- ]
- ]
- },
- {
- "input": "≧̸",
- "description": "Named entity: NotGreaterFullEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2267\u0338"
- ]
- ]
- },
- {
- "input": "&NotGreaterGreater",
- "description": "Bad named entity: NotGreaterGreater without a semi-colon",
- "output": [
- [
- "Character",
- "&NotGreaterGreater"
- ]
- ]
- },
- {
- "input": "≫̸",
- "description": "Named entity: NotGreaterGreater; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226b\u0338"
- ]
- ]
- },
- {
- "input": "&NotGreaterLess",
- "description": "Bad named entity: NotGreaterLess without a semi-colon",
- "output": [
- [
- "Character",
- "&NotGreaterLess"
- ]
- ]
- },
- {
- "input": "≹",
- "description": "Named entity: NotGreaterLess; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2279"
- ]
- ]
- },
- {
- "input": "&NotGreaterSlantEqual",
- "description": "Bad named entity: NotGreaterSlantEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotGreaterSlantEqual"
- ]
- ]
- },
- {
- "input": "⩾̸",
- "description": "Named entity: NotGreaterSlantEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7e\u0338"
- ]
- ]
- },
- {
- "input": "&NotGreaterTilde",
- "description": "Bad named entity: NotGreaterTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&NotGreaterTilde"
- ]
- ]
- },
- {
- "input": "≵",
- "description": "Named entity: NotGreaterTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2275"
- ]
- ]
- },
- {
- "input": "&NotHumpDownHump",
- "description": "Bad named entity: NotHumpDownHump without a semi-colon",
- "output": [
- [
- "Character",
- "&NotHumpDownHump"
- ]
- ]
- },
- {
- "input": "≎̸",
- "description": "Named entity: NotHumpDownHump; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224e\u0338"
- ]
- ]
- },
- {
- "input": "&NotHumpEqual",
- "description": "Bad named entity: NotHumpEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotHumpEqual"
- ]
- ]
- },
- {
- "input": "≏̸",
- "description": "Named entity: NotHumpEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224f\u0338"
- ]
- ]
- },
- {
- "input": "&NotLeftTriangle",
- "description": "Bad named entity: NotLeftTriangle without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLeftTriangle"
- ]
- ]
- },
- {
- "input": "⋪",
- "description": "Named entity: NotLeftTriangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ea"
- ]
- ]
- },
- {
- "input": "&NotLeftTriangleBar",
- "description": "Bad named entity: NotLeftTriangleBar without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLeftTriangleBar"
- ]
- ]
- },
- {
- "input": "⧏̸",
- "description": "Named entity: NotLeftTriangleBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29cf\u0338"
- ]
- ]
- },
- {
- "input": "&NotLeftTriangleEqual",
- "description": "Bad named entity: NotLeftTriangleEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLeftTriangleEqual"
- ]
- ]
- },
- {
- "input": "⋬",
- "description": "Named entity: NotLeftTriangleEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ec"
- ]
- ]
- },
- {
- "input": "&NotLess",
- "description": "Bad named entity: NotLess without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLess"
- ]
- ]
- },
- {
- "input": "≮",
- "description": "Named entity: NotLess; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226e"
- ]
- ]
- },
- {
- "input": "&NotLessEqual",
- "description": "Bad named entity: NotLessEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLessEqual"
- ]
- ]
- },
- {
- "input": "≰",
- "description": "Named entity: NotLessEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2270"
- ]
- ]
- },
- {
- "input": "&NotLessGreater",
- "description": "Bad named entity: NotLessGreater without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLessGreater"
- ]
- ]
- },
- {
- "input": "≸",
- "description": "Named entity: NotLessGreater; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2278"
- ]
- ]
- },
- {
- "input": "&NotLessLess",
- "description": "Bad named entity: NotLessLess without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLessLess"
- ]
- ]
- },
- {
- "input": "≪̸",
- "description": "Named entity: NotLessLess; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226a\u0338"
- ]
- ]
- },
- {
- "input": "&NotLessSlantEqual",
- "description": "Bad named entity: NotLessSlantEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLessSlantEqual"
- ]
- ]
- },
- {
- "input": "⩽̸",
- "description": "Named entity: NotLessSlantEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7d\u0338"
- ]
- ]
- },
- {
- "input": "&NotLessTilde",
- "description": "Bad named entity: NotLessTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&NotLessTilde"
- ]
- ]
- },
- {
- "input": "≴",
- "description": "Named entity: NotLessTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2274"
- ]
- ]
- },
- {
- "input": "&NotNestedGreaterGreater",
- "description": "Bad named entity: NotNestedGreaterGreater without a semi-colon",
- "output": [
- [
- "Character",
- "&NotNestedGreaterGreater"
- ]
- ]
- },
- {
- "input": "⪢̸",
- "description": "Named entity: NotNestedGreaterGreater; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa2\u0338"
- ]
- ]
- },
- {
- "input": "&NotNestedLessLess",
- "description": "Bad named entity: NotNestedLessLess without a semi-colon",
- "output": [
- [
- "Character",
- "&NotNestedLessLess"
- ]
- ]
- },
- {
- "input": "⪡̸",
- "description": "Named entity: NotNestedLessLess; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa1\u0338"
- ]
- ]
- },
- {
- "input": "&NotPrecedes",
- "description": "Bad named entity: NotPrecedes without a semi-colon",
- "output": [
- [
- "Character",
- "&NotPrecedes"
- ]
- ]
- },
- {
- "input": "⊀",
- "description": "Named entity: NotPrecedes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2280"
- ]
- ]
- },
- {
- "input": "&NotPrecedesEqual",
- "description": "Bad named entity: NotPrecedesEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotPrecedesEqual"
- ]
- ]
- },
- {
- "input": "⪯̸",
- "description": "Named entity: NotPrecedesEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aaf\u0338"
- ]
- ]
- },
- {
- "input": "&NotPrecedesSlantEqual",
- "description": "Bad named entity: NotPrecedesSlantEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotPrecedesSlantEqual"
- ]
- ]
- },
- {
- "input": "⋠",
- "description": "Named entity: NotPrecedesSlantEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e0"
- ]
- ]
- },
- {
- "input": "&NotReverseElement",
- "description": "Bad named entity: NotReverseElement without a semi-colon",
- "output": [
- [
- "Character",
- "&NotReverseElement"
- ]
- ]
- },
- {
- "input": "∌",
- "description": "Named entity: NotReverseElement; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220c"
- ]
- ]
- },
- {
- "input": "&NotRightTriangle",
- "description": "Bad named entity: NotRightTriangle without a semi-colon",
- "output": [
- [
- "Character",
- "&NotRightTriangle"
- ]
- ]
- },
- {
- "input": "⋫",
- "description": "Named entity: NotRightTriangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22eb"
- ]
- ]
- },
- {
- "input": "&NotRightTriangleBar",
- "description": "Bad named entity: NotRightTriangleBar without a semi-colon",
- "output": [
- [
- "Character",
- "&NotRightTriangleBar"
- ]
- ]
- },
- {
- "input": "⧐̸",
- "description": "Named entity: NotRightTriangleBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29d0\u0338"
- ]
- ]
- },
- {
- "input": "&NotRightTriangleEqual",
- "description": "Bad named entity: NotRightTriangleEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotRightTriangleEqual"
- ]
- ]
- },
- {
- "input": "⋭",
- "description": "Named entity: NotRightTriangleEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ed"
- ]
- ]
- },
- {
- "input": "&NotSquareSubset",
- "description": "Bad named entity: NotSquareSubset without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSquareSubset"
- ]
- ]
- },
- {
- "input": "⊏̸",
- "description": "Named entity: NotSquareSubset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228f\u0338"
- ]
- ]
- },
- {
- "input": "&NotSquareSubsetEqual",
- "description": "Bad named entity: NotSquareSubsetEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSquareSubsetEqual"
- ]
- ]
- },
- {
- "input": "⋢",
- "description": "Named entity: NotSquareSubsetEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e2"
- ]
- ]
- },
- {
- "input": "&NotSquareSuperset",
- "description": "Bad named entity: NotSquareSuperset without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSquareSuperset"
- ]
- ]
- },
- {
- "input": "⊐̸",
- "description": "Named entity: NotSquareSuperset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2290\u0338"
- ]
- ]
- },
- {
- "input": "&NotSquareSupersetEqual",
- "description": "Bad named entity: NotSquareSupersetEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSquareSupersetEqual"
- ]
- ]
- },
- {
- "input": "⋣",
- "description": "Named entity: NotSquareSupersetEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e3"
- ]
- ]
- },
- {
- "input": "&NotSubset",
- "description": "Bad named entity: NotSubset without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSubset"
- ]
- ]
- },
- {
- "input": "⊂⃒",
- "description": "Named entity: NotSubset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2282\u20d2"
- ]
- ]
- },
- {
- "input": "&NotSubsetEqual",
- "description": "Bad named entity: NotSubsetEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSubsetEqual"
- ]
- ]
- },
- {
- "input": "⊈",
- "description": "Named entity: NotSubsetEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2288"
- ]
- ]
- },
- {
- "input": "&NotSucceeds",
- "description": "Bad named entity: NotSucceeds without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSucceeds"
- ]
- ]
- },
- {
- "input": "⊁",
- "description": "Named entity: NotSucceeds; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2281"
- ]
- ]
- },
- {
- "input": "&NotSucceedsEqual",
- "description": "Bad named entity: NotSucceedsEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSucceedsEqual"
- ]
- ]
- },
- {
- "input": "⪰̸",
- "description": "Named entity: NotSucceedsEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab0\u0338"
- ]
- ]
- },
- {
- "input": "&NotSucceedsSlantEqual",
- "description": "Bad named entity: NotSucceedsSlantEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSucceedsSlantEqual"
- ]
- ]
- },
- {
- "input": "⋡",
- "description": "Named entity: NotSucceedsSlantEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e1"
- ]
- ]
- },
- {
- "input": "&NotSucceedsTilde",
- "description": "Bad named entity: NotSucceedsTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSucceedsTilde"
- ]
- ]
- },
- {
- "input": "≿̸",
- "description": "Named entity: NotSucceedsTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227f\u0338"
- ]
- ]
- },
- {
- "input": "&NotSuperset",
- "description": "Bad named entity: NotSuperset without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSuperset"
- ]
- ]
- },
- {
- "input": "⊃⃒",
- "description": "Named entity: NotSuperset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2283\u20d2"
- ]
- ]
- },
- {
- "input": "&NotSupersetEqual",
- "description": "Bad named entity: NotSupersetEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotSupersetEqual"
- ]
- ]
- },
- {
- "input": "⊉",
- "description": "Named entity: NotSupersetEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2289"
- ]
- ]
- },
- {
- "input": "&NotTilde",
- "description": "Bad named entity: NotTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&NotTilde"
- ]
- ]
- },
- {
- "input": "≁",
- "description": "Named entity: NotTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2241"
- ]
- ]
- },
- {
- "input": "&NotTildeEqual",
- "description": "Bad named entity: NotTildeEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotTildeEqual"
- ]
- ]
- },
- {
- "input": "≄",
- "description": "Named entity: NotTildeEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2244"
- ]
- ]
- },
- {
- "input": "&NotTildeFullEqual",
- "description": "Bad named entity: NotTildeFullEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&NotTildeFullEqual"
- ]
- ]
- },
- {
- "input": "≇",
- "description": "Named entity: NotTildeFullEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2247"
- ]
- ]
- },
- {
- "input": "&NotTildeTilde",
- "description": "Bad named entity: NotTildeTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&NotTildeTilde"
- ]
- ]
- },
- {
- "input": "≉",
- "description": "Named entity: NotTildeTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2249"
- ]
- ]
- },
- {
- "input": "&NotVerticalBar",
- "description": "Bad named entity: NotVerticalBar without a semi-colon",
- "output": [
- [
- "Character",
- "&NotVerticalBar"
- ]
- ]
- },
- {
- "input": "∤",
- "description": "Named entity: NotVerticalBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2224"
- ]
- ]
- },
- {
- "input": "&Nscr",
- "description": "Bad named entity: Nscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Nscr"
- ]
- ]
- },
- {
- "input": "𝒩",
- "description": "Named entity: Nscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udca9"
- ]
- ]
- },
- {
- "input": "Ñ",
- "description": "Named entity: Ntilde without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d1"
- ]
- ]
- },
- {
- "input": "Ñ",
- "description": "Named entity: Ntilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d1"
- ]
- ]
- },
- {
- "input": "&Nu",
- "description": "Bad named entity: Nu without a semi-colon",
- "output": [
- [
- "Character",
- "&Nu"
- ]
- ]
- },
- {
- "input": "Ν",
- "description": "Named entity: Nu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u039d"
- ]
- ]
- },
- {
- "input": "&OElig",
- "description": "Bad named entity: OElig without a semi-colon",
- "output": [
- [
- "Character",
- "&OElig"
- ]
- ]
- },
- {
- "input": "Œ",
- "description": "Named entity: OElig; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0152"
- ]
- ]
- },
- {
- "input": "Ó",
- "description": "Named entity: Oacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d3"
- ]
- ]
- },
- {
- "input": "Ó",
- "description": "Named entity: Oacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d3"
- ]
- ]
- },
- {
- "input": "Ô",
- "description": "Named entity: Ocirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d4"
- ]
- ]
- },
- {
- "input": "Ô",
- "description": "Named entity: Ocirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d4"
- ]
- ]
- },
- {
- "input": "&Ocy",
- "description": "Bad named entity: Ocy without a semi-colon",
- "output": [
- [
- "Character",
- "&Ocy"
- ]
- ]
- },
- {
- "input": "О",
- "description": "Named entity: Ocy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u041e"
- ]
- ]
- },
- {
- "input": "&Odblac",
- "description": "Bad named entity: Odblac without a semi-colon",
- "output": [
- [
- "Character",
- "&Odblac"
- ]
- ]
- },
- {
- "input": "Ő",
- "description": "Named entity: Odblac; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0150"
- ]
- ]
- },
- {
- "input": "&Ofr",
- "description": "Bad named entity: Ofr without a semi-colon",
- "output": [
- [
- "Character",
- "&Ofr"
- ]
- ]
- },
- {
- "input": "𝔒",
- "description": "Named entity: Ofr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd12"
- ]
- ]
- },
- {
- "input": "Ò",
- "description": "Named entity: Ograve without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d2"
- ]
- ]
- },
- {
- "input": "Ò",
- "description": "Named entity: Ograve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d2"
- ]
- ]
- },
- {
- "input": "&Omacr",
- "description": "Bad named entity: Omacr without a semi-colon",
- "output": [
- [
- "Character",
- "&Omacr"
- ]
- ]
- },
- {
- "input": "Ō",
- "description": "Named entity: Omacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u014c"
- ]
- ]
- },
- {
- "input": "&Omega",
- "description": "Bad named entity: Omega without a semi-colon",
- "output": [
- [
- "Character",
- "&Omega"
- ]
- ]
- },
- {
- "input": "Ω",
- "description": "Named entity: Omega; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a9"
- ]
- ]
- },
- {
- "input": "&Omicron",
- "description": "Bad named entity: Omicron without a semi-colon",
- "output": [
- [
- "Character",
- "&Omicron"
- ]
- ]
- },
- {
- "input": "Ο",
- "description": "Named entity: Omicron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u039f"
- ]
- ]
- },
- {
- "input": "&Oopf",
- "description": "Bad named entity: Oopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Oopf"
- ]
- ]
- },
- {
- "input": "𝕆",
- "description": "Named entity: Oopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd46"
- ]
- ]
- },
- {
- "input": "&OpenCurlyDoubleQuote",
- "description": "Bad named entity: OpenCurlyDoubleQuote without a semi-colon",
- "output": [
- [
- "Character",
- "&OpenCurlyDoubleQuote"
- ]
- ]
- },
- {
- "input": "“",
- "description": "Named entity: OpenCurlyDoubleQuote; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201c"
- ]
- ]
- },
- {
- "input": "&OpenCurlyQuote",
- "description": "Bad named entity: OpenCurlyQuote without a semi-colon",
- "output": [
- [
- "Character",
- "&OpenCurlyQuote"
- ]
- ]
- },
- {
- "input": "‘",
- "description": "Named entity: OpenCurlyQuote; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2018"
- ]
- ]
- },
- {
- "input": "&Or",
- "description": "Bad named entity: Or without a semi-colon",
- "output": [
- [
- "Character",
- "&Or"
- ]
- ]
- },
- {
- "input": "⩔",
- "description": "Named entity: Or; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a54"
- ]
- ]
- },
- {
- "input": "&Oscr",
- "description": "Bad named entity: Oscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Oscr"
- ]
- ]
- },
- {
- "input": "𝒪",
- "description": "Named entity: Oscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcaa"
- ]
- ]
- },
- {
- "input": "Ø",
- "description": "Named entity: Oslash without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d8"
- ]
- ]
- },
- {
- "input": "Ø",
- "description": "Named entity: Oslash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d8"
- ]
- ]
- },
- {
- "input": "Õ",
- "description": "Named entity: Otilde without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d5"
- ]
- ]
- },
- {
- "input": "Õ",
- "description": "Named entity: Otilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d5"
- ]
- ]
- },
- {
- "input": "&Otimes",
- "description": "Bad named entity: Otimes without a semi-colon",
- "output": [
- [
- "Character",
- "&Otimes"
- ]
- ]
- },
- {
- "input": "⨷",
- "description": "Named entity: Otimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a37"
- ]
- ]
- },
- {
- "input": "Ö",
- "description": "Named entity: Ouml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d6"
- ]
- ]
- },
- {
- "input": "Ö",
- "description": "Named entity: Ouml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d6"
- ]
- ]
- },
- {
- "input": "&OverBar",
- "description": "Bad named entity: OverBar without a semi-colon",
- "output": [
- [
- "Character",
- "&OverBar"
- ]
- ]
- },
- {
- "input": "‾",
- "description": "Named entity: OverBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u203e"
- ]
- ]
- },
- {
- "input": "&OverBrace",
- "description": "Bad named entity: OverBrace without a semi-colon",
- "output": [
- [
- "Character",
- "&OverBrace"
- ]
- ]
- },
- {
- "input": "⏞",
- "description": "Named entity: OverBrace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23de"
- ]
- ]
- },
- {
- "input": "&OverBracket",
- "description": "Bad named entity: OverBracket without a semi-colon",
- "output": [
- [
- "Character",
- "&OverBracket"
- ]
- ]
- },
- {
- "input": "⎴",
- "description": "Named entity: OverBracket; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b4"
- ]
- ]
- },
- {
- "input": "&OverParenthesis",
- "description": "Bad named entity: OverParenthesis without a semi-colon",
- "output": [
- [
- "Character",
- "&OverParenthesis"
- ]
- ]
- },
- {
- "input": "⏜",
- "description": "Named entity: OverParenthesis; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23dc"
- ]
- ]
- },
- {
- "input": "&PartialD",
- "description": "Bad named entity: PartialD without a semi-colon",
- "output": [
- [
- "Character",
- "&PartialD"
- ]
- ]
- },
- {
- "input": "∂",
- "description": "Named entity: PartialD; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2202"
- ]
- ]
- },
- {
- "input": "&Pcy",
- "description": "Bad named entity: Pcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Pcy"
- ]
- ]
- },
- {
- "input": "П",
- "description": "Named entity: Pcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u041f"
- ]
- ]
- },
- {
- "input": "&Pfr",
- "description": "Bad named entity: Pfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Pfr"
- ]
- ]
- },
- {
- "input": "𝔓",
- "description": "Named entity: Pfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd13"
- ]
- ]
- },
- {
- "input": "&Phi",
- "description": "Bad named entity: Phi without a semi-colon",
- "output": [
- [
- "Character",
- "&Phi"
- ]
- ]
- },
- {
- "input": "Φ",
- "description": "Named entity: Phi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a6"
- ]
- ]
- },
- {
- "input": "&Pi",
- "description": "Bad named entity: Pi without a semi-colon",
- "output": [
- [
- "Character",
- "&Pi"
- ]
- ]
- },
- {
- "input": "Π",
- "description": "Named entity: Pi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a0"
- ]
- ]
- },
- {
- "input": "&PlusMinus",
- "description": "Bad named entity: PlusMinus without a semi-colon",
- "output": [
- [
- "Character",
- "&PlusMinus"
- ]
- ]
- },
- {
- "input": "±",
- "description": "Named entity: PlusMinus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b1"
- ]
- ]
- },
- {
- "input": "&Poincareplane",
- "description": "Bad named entity: Poincareplane without a semi-colon",
- "output": [
- [
- "Character",
- "&Poincareplane"
- ]
- ]
- },
- {
- "input": "ℌ",
- "description": "Named entity: Poincareplane; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210c"
- ]
- ]
- },
- {
- "input": "&Popf",
- "description": "Bad named entity: Popf without a semi-colon",
- "output": [
- [
- "Character",
- "&Popf"
- ]
- ]
- },
- {
- "input": "ℙ",
- "description": "Named entity: Popf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2119"
- ]
- ]
- },
- {
- "input": "&Pr",
- "description": "Bad named entity: Pr without a semi-colon",
- "output": [
- [
- "Character",
- "&Pr"
- ]
- ]
- },
- {
- "input": "⪻",
- "description": "Named entity: Pr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2abb"
- ]
- ]
- },
- {
- "input": "&Precedes",
- "description": "Bad named entity: Precedes without a semi-colon",
- "output": [
- [
- "Character",
- "&Precedes"
- ]
- ]
- },
- {
- "input": "≺",
- "description": "Named entity: Precedes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227a"
- ]
- ]
- },
- {
- "input": "&PrecedesEqual",
- "description": "Bad named entity: PrecedesEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&PrecedesEqual"
- ]
- ]
- },
- {
- "input": "⪯",
- "description": "Named entity: PrecedesEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aaf"
- ]
- ]
- },
- {
- "input": "&PrecedesSlantEqual",
- "description": "Bad named entity: PrecedesSlantEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&PrecedesSlantEqual"
- ]
- ]
- },
- {
- "input": "≼",
- "description": "Named entity: PrecedesSlantEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227c"
- ]
- ]
- },
- {
- "input": "&PrecedesTilde",
- "description": "Bad named entity: PrecedesTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&PrecedesTilde"
- ]
- ]
- },
- {
- "input": "≾",
- "description": "Named entity: PrecedesTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227e"
- ]
- ]
- },
- {
- "input": "&Prime",
- "description": "Bad named entity: Prime without a semi-colon",
- "output": [
- [
- "Character",
- "&Prime"
- ]
- ]
- },
- {
- "input": "″",
- "description": "Named entity: Prime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2033"
- ]
- ]
- },
- {
- "input": "&Product",
- "description": "Bad named entity: Product without a semi-colon",
- "output": [
- [
- "Character",
- "&Product"
- ]
- ]
- },
- {
- "input": "∏",
- "description": "Named entity: Product; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220f"
- ]
- ]
- },
- {
- "input": "&Proportion",
- "description": "Bad named entity: Proportion without a semi-colon",
- "output": [
- [
- "Character",
- "&Proportion"
- ]
- ]
- },
- {
- "input": "∷",
- "description": "Named entity: Proportion; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2237"
- ]
- ]
- },
- {
- "input": "&Proportional",
- "description": "Bad named entity: Proportional without a semi-colon",
- "output": [
- [
- "Character",
- "&Proportional"
- ]
- ]
- },
- {
- "input": "∝",
- "description": "Named entity: Proportional; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221d"
- ]
- ]
- },
- {
- "input": "&Pscr",
- "description": "Bad named entity: Pscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Pscr"
- ]
- ]
- },
- {
- "input": "𝒫",
- "description": "Named entity: Pscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcab"
- ]
- ]
- },
- {
- "input": "&Psi",
- "description": "Bad named entity: Psi without a semi-colon",
- "output": [
- [
- "Character",
- "&Psi"
- ]
- ]
- },
- {
- "input": "Ψ",
- "description": "Named entity: Psi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a8"
- ]
- ]
- },
- {
- "input": """,
- "description": "Named entity: QUOT without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\""
- ]
- ]
- },
- {
- "input": """,
- "description": "Named entity: QUOT; with a semi-colon",
- "output": [
- [
- "Character",
- "\""
- ]
- ]
- },
- {
- "input": "&Qfr",
- "description": "Bad named entity: Qfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Qfr"
- ]
- ]
- },
- {
- "input": "𝔔",
- "description": "Named entity: Qfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd14"
- ]
- ]
- },
- {
- "input": "&Qopf",
- "description": "Bad named entity: Qopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Qopf"
- ]
- ]
- },
- {
- "input": "ℚ",
- "description": "Named entity: Qopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211a"
- ]
- ]
- },
- {
- "input": "&Qscr",
- "description": "Bad named entity: Qscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Qscr"
- ]
- ]
- },
- {
- "input": "𝒬",
- "description": "Named entity: Qscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcac"
- ]
- ]
- },
- {
- "input": "&RBarr",
- "description": "Bad named entity: RBarr without a semi-colon",
- "output": [
- [
- "Character",
- "&RBarr"
- ]
- ]
- },
- {
- "input": "⤐",
- "description": "Named entity: RBarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2910"
- ]
- ]
- },
- {
- "input": "®",
- "description": "Named entity: REG without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ae"
- ]
- ]
- },
- {
- "input": "®",
- "description": "Named entity: REG; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ae"
- ]
- ]
- },
- {
- "input": "&Racute",
- "description": "Bad named entity: Racute without a semi-colon",
- "output": [
- [
- "Character",
- "&Racute"
- ]
- ]
- },
- {
- "input": "Ŕ",
- "description": "Named entity: Racute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0154"
- ]
- ]
- },
- {
- "input": "&Rang",
- "description": "Bad named entity: Rang without a semi-colon",
- "output": [
- [
- "Character",
- "&Rang"
- ]
- ]
- },
- {
- "input": "⟫",
- "description": "Named entity: Rang; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27eb"
- ]
- ]
- },
- {
- "input": "&Rarr",
- "description": "Bad named entity: Rarr without a semi-colon",
- "output": [
- [
- "Character",
- "&Rarr"
- ]
- ]
- },
- {
- "input": "↠",
- "description": "Named entity: Rarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a0"
- ]
- ]
- },
- {
- "input": "&Rarrtl",
- "description": "Bad named entity: Rarrtl without a semi-colon",
- "output": [
- [
- "Character",
- "&Rarrtl"
- ]
- ]
- },
- {
- "input": "⤖",
- "description": "Named entity: Rarrtl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2916"
- ]
- ]
- },
- {
- "input": "&Rcaron",
- "description": "Bad named entity: Rcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Rcaron"
- ]
- ]
- },
- {
- "input": "Ř",
- "description": "Named entity: Rcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0158"
- ]
- ]
- },
- {
- "input": "&Rcedil",
- "description": "Bad named entity: Rcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&Rcedil"
- ]
- ]
- },
- {
- "input": "Ŗ",
- "description": "Named entity: Rcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0156"
- ]
- ]
- },
- {
- "input": "&Rcy",
- "description": "Bad named entity: Rcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Rcy"
- ]
- ]
- },
- {
- "input": "Р",
- "description": "Named entity: Rcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0420"
- ]
- ]
- },
- {
- "input": "&Re",
- "description": "Bad named entity: Re without a semi-colon",
- "output": [
- [
- "Character",
- "&Re"
- ]
- ]
- },
- {
- "input": "ℜ",
- "description": "Named entity: Re; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211c"
- ]
- ]
- },
- {
- "input": "&ReverseElement",
- "description": "Bad named entity: ReverseElement without a semi-colon",
- "output": [
- [
- "Character",
- "&ReverseElement"
- ]
- ]
- },
- {
- "input": "∋",
- "description": "Named entity: ReverseElement; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220b"
- ]
- ]
- },
- {
- "input": "&ReverseEquilibrium",
- "description": "Bad named entity: ReverseEquilibrium without a semi-colon",
- "output": [
- [
- "Character",
- "&ReverseEquilibrium"
- ]
- ]
- },
- {
- "input": "⇋",
- "description": "Named entity: ReverseEquilibrium; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cb"
- ]
- ]
- },
- {
- "input": "&ReverseUpEquilibrium",
- "description": "Bad named entity: ReverseUpEquilibrium without a semi-colon",
- "output": [
- [
- "Character",
- "&ReverseUpEquilibrium"
- ]
- ]
- },
- {
- "input": "⥯",
- "description": "Named entity: ReverseUpEquilibrium; with a semi-colon",
- "output": [
- [
- "Character",
- "\u296f"
- ]
- ]
- },
- {
- "input": "&Rfr",
- "description": "Bad named entity: Rfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Rfr"
- ]
- ]
- },
- {
- "input": "ℜ",
- "description": "Named entity: Rfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211c"
- ]
- ]
- },
- {
- "input": "&Rho",
- "description": "Bad named entity: Rho without a semi-colon",
- "output": [
- [
- "Character",
- "&Rho"
- ]
- ]
- },
- {
- "input": "Ρ",
- "description": "Named entity: Rho; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a1"
- ]
- ]
- },
- {
- "input": "&RightAngleBracket",
- "description": "Bad named entity: RightAngleBracket without a semi-colon",
- "output": [
- [
- "Character",
- "&RightAngleBracket"
- ]
- ]
- },
- {
- "input": "⟩",
- "description": "Named entity: RightAngleBracket; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e9"
- ]
- ]
- },
- {
- "input": "&RightArrow",
- "description": "Bad named entity: RightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&RightArrow"
- ]
- ]
- },
- {
- "input": "→",
- "description": "Named entity: RightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2192"
- ]
- ]
- },
- {
- "input": "&RightArrowBar",
- "description": "Bad named entity: RightArrowBar without a semi-colon",
- "output": [
- [
- "Character",
- "&RightArrowBar"
- ]
- ]
- },
- {
- "input": "⇥",
- "description": "Named entity: RightArrowBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21e5"
- ]
- ]
- },
- {
- "input": "&RightArrowLeftArrow",
- "description": "Bad named entity: RightArrowLeftArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&RightArrowLeftArrow"
- ]
- ]
- },
- {
- "input": "⇄",
- "description": "Named entity: RightArrowLeftArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c4"
- ]
- ]
- },
- {
- "input": "&RightCeiling",
- "description": "Bad named entity: RightCeiling without a semi-colon",
- "output": [
- [
- "Character",
- "&RightCeiling"
- ]
- ]
- },
- {
- "input": "⌉",
- "description": "Named entity: RightCeiling; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2309"
- ]
- ]
- },
- {
- "input": "&RightDoubleBracket",
- "description": "Bad named entity: RightDoubleBracket without a semi-colon",
- "output": [
- [
- "Character",
- "&RightDoubleBracket"
- ]
- ]
- },
- {
- "input": "⟧",
- "description": "Named entity: RightDoubleBracket; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e7"
- ]
- ]
- },
- {
- "input": "&RightDownTeeVector",
- "description": "Bad named entity: RightDownTeeVector without a semi-colon",
- "output": [
- [
- "Character",
- "&RightDownTeeVector"
- ]
- ]
- },
- {
- "input": "⥝",
- "description": "Named entity: RightDownTeeVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u295d"
- ]
- ]
- },
- {
- "input": "&RightDownVector",
- "description": "Bad named entity: RightDownVector without a semi-colon",
- "output": [
- [
- "Character",
- "&RightDownVector"
- ]
- ]
- },
- {
- "input": "⇂",
- "description": "Named entity: RightDownVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c2"
- ]
- ]
- },
- {
- "input": "&RightDownVectorBar",
- "description": "Bad named entity: RightDownVectorBar without a semi-colon",
- "output": [
- [
- "Character",
- "&RightDownVectorBar"
- ]
- ]
- },
- {
- "input": "⥕",
- "description": "Named entity: RightDownVectorBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2955"
- ]
- ]
- },
- {
- "input": "&RightFloor",
- "description": "Bad named entity: RightFloor without a semi-colon",
- "output": [
- [
- "Character",
- "&RightFloor"
- ]
- ]
- },
- {
- "input": "⌋",
- "description": "Named entity: RightFloor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u230b"
- ]
- ]
- },
- {
- "input": "&RightTee",
- "description": "Bad named entity: RightTee without a semi-colon",
- "output": [
- [
- "Character",
- "&RightTee"
- ]
- ]
- },
- {
- "input": "⊢",
- "description": "Named entity: RightTee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a2"
- ]
- ]
- },
- {
- "input": "&RightTeeArrow",
- "description": "Bad named entity: RightTeeArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&RightTeeArrow"
- ]
- ]
- },
- {
- "input": "↦",
- "description": "Named entity: RightTeeArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a6"
- ]
- ]
- },
- {
- "input": "&RightTeeVector",
- "description": "Bad named entity: RightTeeVector without a semi-colon",
- "output": [
- [
- "Character",
- "&RightTeeVector"
- ]
- ]
- },
- {
- "input": "⥛",
- "description": "Named entity: RightTeeVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u295b"
- ]
- ]
- },
- {
- "input": "&RightTriangle",
- "description": "Bad named entity: RightTriangle without a semi-colon",
- "output": [
- [
- "Character",
- "&RightTriangle"
- ]
- ]
- },
- {
- "input": "⊳",
- "description": "Named entity: RightTriangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b3"
- ]
- ]
- },
- {
- "input": "&RightTriangleBar",
- "description": "Bad named entity: RightTriangleBar without a semi-colon",
- "output": [
- [
- "Character",
- "&RightTriangleBar"
- ]
- ]
- },
- {
- "input": "⧐",
- "description": "Named entity: RightTriangleBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29d0"
- ]
- ]
- },
- {
- "input": "&RightTriangleEqual",
- "description": "Bad named entity: RightTriangleEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&RightTriangleEqual"
- ]
- ]
- },
- {
- "input": "⊵",
- "description": "Named entity: RightTriangleEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b5"
- ]
- ]
- },
- {
- "input": "&RightUpDownVector",
- "description": "Bad named entity: RightUpDownVector without a semi-colon",
- "output": [
- [
- "Character",
- "&RightUpDownVector"
- ]
- ]
- },
- {
- "input": "⥏",
- "description": "Named entity: RightUpDownVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u294f"
- ]
- ]
- },
- {
- "input": "&RightUpTeeVector",
- "description": "Bad named entity: RightUpTeeVector without a semi-colon",
- "output": [
- [
- "Character",
- "&RightUpTeeVector"
- ]
- ]
- },
- {
- "input": "⥜",
- "description": "Named entity: RightUpTeeVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u295c"
- ]
- ]
- },
- {
- "input": "&RightUpVector",
- "description": "Bad named entity: RightUpVector without a semi-colon",
- "output": [
- [
- "Character",
- "&RightUpVector"
- ]
- ]
- },
- {
- "input": "↾",
- "description": "Named entity: RightUpVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21be"
- ]
- ]
- },
- {
- "input": "&RightUpVectorBar",
- "description": "Bad named entity: RightUpVectorBar without a semi-colon",
- "output": [
- [
- "Character",
- "&RightUpVectorBar"
- ]
- ]
- },
- {
- "input": "⥔",
- "description": "Named entity: RightUpVectorBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2954"
- ]
- ]
- },
- {
- "input": "&RightVector",
- "description": "Bad named entity: RightVector without a semi-colon",
- "output": [
- [
- "Character",
- "&RightVector"
- ]
- ]
- },
- {
- "input": "⇀",
- "description": "Named entity: RightVector; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c0"
- ]
- ]
- },
- {
- "input": "&RightVectorBar",
- "description": "Bad named entity: RightVectorBar without a semi-colon",
- "output": [
- [
- "Character",
- "&RightVectorBar"
- ]
- ]
- },
- {
- "input": "⥓",
- "description": "Named entity: RightVectorBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2953"
- ]
- ]
- },
- {
- "input": "&Rightarrow",
- "description": "Bad named entity: Rightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Rightarrow"
- ]
- ]
- },
- {
- "input": "⇒",
- "description": "Named entity: Rightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d2"
- ]
- ]
- },
- {
- "input": "&Ropf",
- "description": "Bad named entity: Ropf without a semi-colon",
- "output": [
- [
- "Character",
- "&Ropf"
- ]
- ]
- },
- {
- "input": "ℝ",
- "description": "Named entity: Ropf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211d"
- ]
- ]
- },
- {
- "input": "&RoundImplies",
- "description": "Bad named entity: RoundImplies without a semi-colon",
- "output": [
- [
- "Character",
- "&RoundImplies"
- ]
- ]
- },
- {
- "input": "⥰",
- "description": "Named entity: RoundImplies; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2970"
- ]
- ]
- },
- {
- "input": "&Rrightarrow",
- "description": "Bad named entity: Rrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Rrightarrow"
- ]
- ]
- },
- {
- "input": "⇛",
- "description": "Named entity: Rrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21db"
- ]
- ]
- },
- {
- "input": "&Rscr",
- "description": "Bad named entity: Rscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Rscr"
- ]
- ]
- },
- {
- "input": "ℛ",
- "description": "Named entity: Rscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211b"
- ]
- ]
- },
- {
- "input": "&Rsh",
- "description": "Bad named entity: Rsh without a semi-colon",
- "output": [
- [
- "Character",
- "&Rsh"
- ]
- ]
- },
- {
- "input": "↱",
- "description": "Named entity: Rsh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b1"
- ]
- ]
- },
- {
- "input": "&RuleDelayed",
- "description": "Bad named entity: RuleDelayed without a semi-colon",
- "output": [
- [
- "Character",
- "&RuleDelayed"
- ]
- ]
- },
- {
- "input": "⧴",
- "description": "Named entity: RuleDelayed; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29f4"
- ]
- ]
- },
- {
- "input": "&SHCHcy",
- "description": "Bad named entity: SHCHcy without a semi-colon",
- "output": [
- [
- "Character",
- "&SHCHcy"
- ]
- ]
- },
- {
- "input": "Щ",
- "description": "Named entity: SHCHcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0429"
- ]
- ]
- },
- {
- "input": "&SHcy",
- "description": "Bad named entity: SHcy without a semi-colon",
- "output": [
- [
- "Character",
- "&SHcy"
- ]
- ]
- },
- {
- "input": "Ш",
- "description": "Named entity: SHcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0428"
- ]
- ]
- },
- {
- "input": "&SOFTcy",
- "description": "Bad named entity: SOFTcy without a semi-colon",
- "output": [
- [
- "Character",
- "&SOFTcy"
- ]
- ]
- },
- {
- "input": "Ь",
- "description": "Named entity: SOFTcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u042c"
- ]
- ]
- },
- {
- "input": "&Sacute",
- "description": "Bad named entity: Sacute without a semi-colon",
- "output": [
- [
- "Character",
- "&Sacute"
- ]
- ]
- },
- {
- "input": "Ś",
- "description": "Named entity: Sacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u015a"
- ]
- ]
- },
- {
- "input": "&Sc",
- "description": "Bad named entity: Sc without a semi-colon",
- "output": [
- [
- "Character",
- "&Sc"
- ]
- ]
- },
- {
- "input": "⪼",
- "description": "Named entity: Sc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2abc"
- ]
- ]
- },
- {
- "input": "&Scaron",
- "description": "Bad named entity: Scaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Scaron"
- ]
- ]
- },
- {
- "input": "Š",
- "description": "Named entity: Scaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0160"
- ]
- ]
- },
- {
- "input": "&Scedil",
- "description": "Bad named entity: Scedil without a semi-colon",
- "output": [
- [
- "Character",
- "&Scedil"
- ]
- ]
- },
- {
- "input": "Ş",
- "description": "Named entity: Scedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u015e"
- ]
- ]
- },
- {
- "input": "&Scirc",
- "description": "Bad named entity: Scirc without a semi-colon",
- "output": [
- [
- "Character",
- "&Scirc"
- ]
- ]
- },
- {
- "input": "Ŝ",
- "description": "Named entity: Scirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u015c"
- ]
- ]
- },
- {
- "input": "&Scy",
- "description": "Bad named entity: Scy without a semi-colon",
- "output": [
- [
- "Character",
- "&Scy"
- ]
- ]
- },
- {
- "input": "С",
- "description": "Named entity: Scy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0421"
- ]
- ]
- },
- {
- "input": "&Sfr",
- "description": "Bad named entity: Sfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Sfr"
- ]
- ]
- },
- {
- "input": "𝔖",
- "description": "Named entity: Sfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd16"
- ]
- ]
- },
- {
- "input": "&ShortDownArrow",
- "description": "Bad named entity: ShortDownArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&ShortDownArrow"
- ]
- ]
- },
- {
- "input": "↓",
- "description": "Named entity: ShortDownArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2193"
- ]
- ]
- },
- {
- "input": "&ShortLeftArrow",
- "description": "Bad named entity: ShortLeftArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&ShortLeftArrow"
- ]
- ]
- },
- {
- "input": "←",
- "description": "Named entity: ShortLeftArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2190"
- ]
- ]
- },
- {
- "input": "&ShortRightArrow",
- "description": "Bad named entity: ShortRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&ShortRightArrow"
- ]
- ]
- },
- {
- "input": "→",
- "description": "Named entity: ShortRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2192"
- ]
- ]
- },
- {
- "input": "&ShortUpArrow",
- "description": "Bad named entity: ShortUpArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&ShortUpArrow"
- ]
- ]
- },
- {
- "input": "↑",
- "description": "Named entity: ShortUpArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2191"
- ]
- ]
- },
- {
- "input": "&Sigma",
- "description": "Bad named entity: Sigma without a semi-colon",
- "output": [
- [
- "Character",
- "&Sigma"
- ]
- ]
- },
- {
- "input": "Σ",
- "description": "Named entity: Sigma; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a3"
- ]
- ]
- },
- {
- "input": "&SmallCircle",
- "description": "Bad named entity: SmallCircle without a semi-colon",
- "output": [
- [
- "Character",
- "&SmallCircle"
- ]
- ]
- },
- {
- "input": "∘",
- "description": "Named entity: SmallCircle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2218"
- ]
- ]
- },
- {
- "input": "&Sopf",
- "description": "Bad named entity: Sopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Sopf"
- ]
- ]
- },
- {
- "input": "𝕊",
- "description": "Named entity: Sopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd4a"
- ]
- ]
- },
- {
- "input": "&Sqrt",
- "description": "Bad named entity: Sqrt without a semi-colon",
- "output": [
- [
- "Character",
- "&Sqrt"
- ]
- ]
- },
- {
- "input": "√",
- "description": "Named entity: Sqrt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221a"
- ]
- ]
- },
- {
- "input": "&Square",
- "description": "Bad named entity: Square without a semi-colon",
- "output": [
- [
- "Character",
- "&Square"
- ]
- ]
- },
- {
- "input": "□",
- "description": "Named entity: Square; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25a1"
- ]
- ]
- },
- {
- "input": "&SquareIntersection",
- "description": "Bad named entity: SquareIntersection without a semi-colon",
- "output": [
- [
- "Character",
- "&SquareIntersection"
- ]
- ]
- },
- {
- "input": "⊓",
- "description": "Named entity: SquareIntersection; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2293"
- ]
- ]
- },
- {
- "input": "&SquareSubset",
- "description": "Bad named entity: SquareSubset without a semi-colon",
- "output": [
- [
- "Character",
- "&SquareSubset"
- ]
- ]
- },
- {
- "input": "⊏",
- "description": "Named entity: SquareSubset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228f"
- ]
- ]
- },
- {
- "input": "&SquareSubsetEqual",
- "description": "Bad named entity: SquareSubsetEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&SquareSubsetEqual"
- ]
- ]
- },
- {
- "input": "⊑",
- "description": "Named entity: SquareSubsetEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2291"
- ]
- ]
- },
- {
- "input": "&SquareSuperset",
- "description": "Bad named entity: SquareSuperset without a semi-colon",
- "output": [
- [
- "Character",
- "&SquareSuperset"
- ]
- ]
- },
- {
- "input": "⊐",
- "description": "Named entity: SquareSuperset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2290"
- ]
- ]
- },
- {
- "input": "&SquareSupersetEqual",
- "description": "Bad named entity: SquareSupersetEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&SquareSupersetEqual"
- ]
- ]
- },
- {
- "input": "⊒",
- "description": "Named entity: SquareSupersetEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2292"
- ]
- ]
- },
- {
- "input": "&SquareUnion",
- "description": "Bad named entity: SquareUnion without a semi-colon",
- "output": [
- [
- "Character",
- "&SquareUnion"
- ]
- ]
- },
- {
- "input": "⊔",
- "description": "Named entity: SquareUnion; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2294"
- ]
- ]
- },
- {
- "input": "&Sscr",
- "description": "Bad named entity: Sscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Sscr"
- ]
- ]
- },
- {
- "input": "𝒮",
- "description": "Named entity: Sscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcae"
- ]
- ]
- },
- {
- "input": "&Star",
- "description": "Bad named entity: Star without a semi-colon",
- "output": [
- [
- "Character",
- "&Star"
- ]
- ]
- },
- {
- "input": "⋆",
- "description": "Named entity: Star; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c6"
- ]
- ]
- },
- {
- "input": "&Sub",
- "description": "Bad named entity: Sub without a semi-colon",
- "output": [
- [
- "Character",
- "&Sub"
- ]
- ]
- },
- {
- "input": "⋐",
- "description": "Named entity: Sub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d0"
- ]
- ]
- },
- {
- "input": "&Subset",
- "description": "Bad named entity: Subset without a semi-colon",
- "output": [
- [
- "Character",
- "&Subset"
- ]
- ]
- },
- {
- "input": "⋐",
- "description": "Named entity: Subset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d0"
- ]
- ]
- },
- {
- "input": "&SubsetEqual",
- "description": "Bad named entity: SubsetEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&SubsetEqual"
- ]
- ]
- },
- {
- "input": "⊆",
- "description": "Named entity: SubsetEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2286"
- ]
- ]
- },
- {
- "input": "&Succeeds",
- "description": "Bad named entity: Succeeds without a semi-colon",
- "output": [
- [
- "Character",
- "&Succeeds"
- ]
- ]
- },
- {
- "input": "≻",
- "description": "Named entity: Succeeds; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227b"
- ]
- ]
- },
- {
- "input": "&SucceedsEqual",
- "description": "Bad named entity: SucceedsEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&SucceedsEqual"
- ]
- ]
- },
- {
- "input": "⪰",
- "description": "Named entity: SucceedsEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab0"
- ]
- ]
- },
- {
- "input": "&SucceedsSlantEqual",
- "description": "Bad named entity: SucceedsSlantEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&SucceedsSlantEqual"
- ]
- ]
- },
- {
- "input": "≽",
- "description": "Named entity: SucceedsSlantEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227d"
- ]
- ]
- },
- {
- "input": "&SucceedsTilde",
- "description": "Bad named entity: SucceedsTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&SucceedsTilde"
- ]
- ]
- },
- {
- "input": "≿",
- "description": "Named entity: SucceedsTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227f"
- ]
- ]
- },
- {
- "input": "&SuchThat",
- "description": "Bad named entity: SuchThat without a semi-colon",
- "output": [
- [
- "Character",
- "&SuchThat"
- ]
- ]
- },
- {
- "input": "∋",
- "description": "Named entity: SuchThat; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220b"
- ]
- ]
- },
- {
- "input": "&Sum",
- "description": "Bad named entity: Sum without a semi-colon",
- "output": [
- [
- "Character",
- "&Sum"
- ]
- ]
- },
- {
- "input": "∑",
- "description": "Named entity: Sum; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2211"
- ]
- ]
- },
- {
- "input": "&Sup",
- "description": "Bad named entity: Sup without a semi-colon",
- "output": [
- [
- "Character",
- "&Sup"
- ]
- ]
- },
- {
- "input": "⋑",
- "description": "Named entity: Sup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d1"
- ]
- ]
- },
- {
- "input": "&Superset",
- "description": "Bad named entity: Superset without a semi-colon",
- "output": [
- [
- "Character",
- "&Superset"
- ]
- ]
- },
- {
- "input": "⊃",
- "description": "Named entity: Superset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2283"
- ]
- ]
- },
- {
- "input": "&SupersetEqual",
- "description": "Bad named entity: SupersetEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&SupersetEqual"
- ]
- ]
- },
- {
- "input": "⊇",
- "description": "Named entity: SupersetEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2287"
- ]
- ]
- },
- {
- "input": "&Supset",
- "description": "Bad named entity: Supset without a semi-colon",
- "output": [
- [
- "Character",
- "&Supset"
- ]
- ]
- },
- {
- "input": "⋑",
- "description": "Named entity: Supset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d1"
- ]
- ]
- },
- {
- "input": "Þ",
- "description": "Named entity: THORN without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00de"
- ]
- ]
- },
- {
- "input": "Þ",
- "description": "Named entity: THORN; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00de"
- ]
- ]
- },
- {
- "input": "&TRADE",
- "description": "Bad named entity: TRADE without a semi-colon",
- "output": [
- [
- "Character",
- "&TRADE"
- ]
- ]
- },
- {
- "input": "™",
- "description": "Named entity: TRADE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2122"
- ]
- ]
- },
- {
- "input": "&TSHcy",
- "description": "Bad named entity: TSHcy without a semi-colon",
- "output": [
- [
- "Character",
- "&TSHcy"
- ]
- ]
- },
- {
- "input": "Ћ",
- "description": "Named entity: TSHcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u040b"
- ]
- ]
- },
- {
- "input": "&TScy",
- "description": "Bad named entity: TScy without a semi-colon",
- "output": [
- [
- "Character",
- "&TScy"
- ]
- ]
- },
- {
- "input": "Ц",
- "description": "Named entity: TScy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0426"
- ]
- ]
- },
- {
- "input": "&Tab",
- "description": "Bad named entity: Tab without a semi-colon",
- "output": [
- [
- "Character",
- "&Tab"
- ]
- ]
- },
- {
- "input": "	",
- "description": "Named entity: Tab; with a semi-colon",
- "output": [
- [
- "Character",
- "\t"
- ]
- ]
- },
- {
- "input": "&Tau",
- "description": "Bad named entity: Tau without a semi-colon",
- "output": [
- [
- "Character",
- "&Tau"
- ]
- ]
- },
- {
- "input": "Τ",
- "description": "Named entity: Tau; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a4"
- ]
- ]
- },
- {
- "input": "&Tcaron",
- "description": "Bad named entity: Tcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Tcaron"
- ]
- ]
- },
- {
- "input": "Ť",
- "description": "Named entity: Tcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0164"
- ]
- ]
- },
- {
- "input": "&Tcedil",
- "description": "Bad named entity: Tcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&Tcedil"
- ]
- ]
- },
- {
- "input": "Ţ",
- "description": "Named entity: Tcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0162"
- ]
- ]
- },
- {
- "input": "&Tcy",
- "description": "Bad named entity: Tcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Tcy"
- ]
- ]
- },
- {
- "input": "Т",
- "description": "Named entity: Tcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0422"
- ]
- ]
- },
- {
- "input": "&Tfr",
- "description": "Bad named entity: Tfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Tfr"
- ]
- ]
- },
- {
- "input": "𝔗",
- "description": "Named entity: Tfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd17"
- ]
- ]
- },
- {
- "input": "&Therefore",
- "description": "Bad named entity: Therefore without a semi-colon",
- "output": [
- [
- "Character",
- "&Therefore"
- ]
- ]
- },
- {
- "input": "∴",
- "description": "Named entity: Therefore; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2234"
- ]
- ]
- },
- {
- "input": "&Theta",
- "description": "Bad named entity: Theta without a semi-colon",
- "output": [
- [
- "Character",
- "&Theta"
- ]
- ]
- },
- {
- "input": "Θ",
- "description": "Named entity: Theta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0398"
- ]
- ]
- },
- {
- "input": "&ThickSpace",
- "description": "Bad named entity: ThickSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&ThickSpace"
- ]
- ]
- },
- {
- "input": "  ",
- "description": "Named entity: ThickSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u205f\u200a"
- ]
- ]
- },
- {
- "input": "&ThinSpace",
- "description": "Bad named entity: ThinSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&ThinSpace"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: ThinSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2009"
- ]
- ]
- },
- {
- "input": "&Tilde",
- "description": "Bad named entity: Tilde without a semi-colon",
- "output": [
- [
- "Character",
- "&Tilde"
- ]
- ]
- },
- {
- "input": "∼",
- "description": "Named entity: Tilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223c"
- ]
- ]
- },
- {
- "input": "&TildeEqual",
- "description": "Bad named entity: TildeEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&TildeEqual"
- ]
- ]
- },
- {
- "input": "≃",
- "description": "Named entity: TildeEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2243"
- ]
- ]
- },
- {
- "input": "&TildeFullEqual",
- "description": "Bad named entity: TildeFullEqual without a semi-colon",
- "output": [
- [
- "Character",
- "&TildeFullEqual"
- ]
- ]
- },
- {
- "input": "≅",
- "description": "Named entity: TildeFullEqual; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2245"
- ]
- ]
- },
- {
- "input": "&TildeTilde",
- "description": "Bad named entity: TildeTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&TildeTilde"
- ]
- ]
- },
- {
- "input": "≈",
- "description": "Named entity: TildeTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2248"
- ]
- ]
- },
- {
- "input": "&Topf",
- "description": "Bad named entity: Topf without a semi-colon",
- "output": [
- [
- "Character",
- "&Topf"
- ]
- ]
- },
- {
- "input": "𝕋",
- "description": "Named entity: Topf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd4b"
- ]
- ]
- },
- {
- "input": "&TripleDot",
- "description": "Bad named entity: TripleDot without a semi-colon",
- "output": [
- [
- "Character",
- "&TripleDot"
- ]
- ]
- },
- {
- "input": "⃛",
- "description": "Named entity: TripleDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u20db"
- ]
- ]
- },
- {
- "input": "&Tscr",
- "description": "Bad named entity: Tscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Tscr"
- ]
- ]
- },
- {
- "input": "𝒯",
- "description": "Named entity: Tscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcaf"
- ]
- ]
- },
- {
- "input": "&Tstrok",
- "description": "Bad named entity: Tstrok without a semi-colon",
- "output": [
- [
- "Character",
- "&Tstrok"
- ]
- ]
- },
- {
- "input": "Ŧ",
- "description": "Named entity: Tstrok; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0166"
- ]
- ]
- },
- {
- "input": "Ú",
- "description": "Named entity: Uacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00da"
- ]
- ]
- },
- {
- "input": "Ú",
- "description": "Named entity: Uacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00da"
- ]
- ]
- },
- {
- "input": "&Uarr",
- "description": "Bad named entity: Uarr without a semi-colon",
- "output": [
- [
- "Character",
- "&Uarr"
- ]
- ]
- },
- {
- "input": "↟",
- "description": "Named entity: Uarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219f"
- ]
- ]
- },
- {
- "input": "&Uarrocir",
- "description": "Bad named entity: Uarrocir without a semi-colon",
- "output": [
- [
- "Character",
- "&Uarrocir"
- ]
- ]
- },
- {
- "input": "⥉",
- "description": "Named entity: Uarrocir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2949"
- ]
- ]
- },
- {
- "input": "&Ubrcy",
- "description": "Bad named entity: Ubrcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Ubrcy"
- ]
- ]
- },
- {
- "input": "Ў",
- "description": "Named entity: Ubrcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u040e"
- ]
- ]
- },
- {
- "input": "&Ubreve",
- "description": "Bad named entity: Ubreve without a semi-colon",
- "output": [
- [
- "Character",
- "&Ubreve"
- ]
- ]
- },
- {
- "input": "Ŭ",
- "description": "Named entity: Ubreve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u016c"
- ]
- ]
- },
- {
- "input": "Û",
- "description": "Named entity: Ucirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00db"
- ]
- ]
- },
- {
- "input": "Û",
- "description": "Named entity: Ucirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00db"
- ]
- ]
- },
- {
- "input": "&Ucy",
- "description": "Bad named entity: Ucy without a semi-colon",
- "output": [
- [
- "Character",
- "&Ucy"
- ]
- ]
- },
- {
- "input": "У",
- "description": "Named entity: Ucy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0423"
- ]
- ]
- },
- {
- "input": "&Udblac",
- "description": "Bad named entity: Udblac without a semi-colon",
- "output": [
- [
- "Character",
- "&Udblac"
- ]
- ]
- },
- {
- "input": "Ű",
- "description": "Named entity: Udblac; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0170"
- ]
- ]
- },
- {
- "input": "&Ufr",
- "description": "Bad named entity: Ufr without a semi-colon",
- "output": [
- [
- "Character",
- "&Ufr"
- ]
- ]
- },
- {
- "input": "𝔘",
- "description": "Named entity: Ufr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd18"
- ]
- ]
- },
- {
- "input": "Ù",
- "description": "Named entity: Ugrave without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d9"
- ]
- ]
- },
- {
- "input": "Ù",
- "description": "Named entity: Ugrave; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d9"
- ]
- ]
- },
- {
- "input": "&Umacr",
- "description": "Bad named entity: Umacr without a semi-colon",
- "output": [
- [
- "Character",
- "&Umacr"
- ]
- ]
- },
- {
- "input": "Ū",
- "description": "Named entity: Umacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u016a"
- ]
- ]
- },
- {
- "input": "&UnderBar",
- "description": "Bad named entity: UnderBar without a semi-colon",
- "output": [
- [
- "Character",
- "&UnderBar"
- ]
- ]
- },
- {
- "input": "_",
- "description": "Named entity: UnderBar; with a semi-colon",
- "output": [
- [
- "Character",
- "_"
- ]
- ]
- },
- {
- "input": "&UnderBrace",
- "description": "Bad named entity: UnderBrace without a semi-colon",
- "output": [
- [
- "Character",
- "&UnderBrace"
- ]
- ]
- },
- {
- "input": "⏟",
- "description": "Named entity: UnderBrace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23df"
- ]
- ]
- },
- {
- "input": "&UnderBracket",
- "description": "Bad named entity: UnderBracket without a semi-colon",
- "output": [
- [
- "Character",
- "&UnderBracket"
- ]
- ]
- },
- {
- "input": "⎵",
- "description": "Named entity: UnderBracket; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b5"
- ]
- ]
- },
- {
- "input": "&UnderParenthesis",
- "description": "Bad named entity: UnderParenthesis without a semi-colon",
- "output": [
- [
- "Character",
- "&UnderParenthesis"
- ]
- ]
- },
- {
- "input": "⏝",
- "description": "Named entity: UnderParenthesis; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23dd"
- ]
- ]
- },
- {
- "input": "&Union",
- "description": "Bad named entity: Union without a semi-colon",
- "output": [
- [
- "Character",
- "&Union"
- ]
- ]
- },
- {
- "input": "⋃",
- "description": "Named entity: Union; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c3"
- ]
- ]
- },
- {
- "input": "&UnionPlus",
- "description": "Bad named entity: UnionPlus without a semi-colon",
- "output": [
- [
- "Character",
- "&UnionPlus"
- ]
- ]
- },
- {
- "input": "⊎",
- "description": "Named entity: UnionPlus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228e"
- ]
- ]
- },
- {
- "input": "&Uogon",
- "description": "Bad named entity: Uogon without a semi-colon",
- "output": [
- [
- "Character",
- "&Uogon"
- ]
- ]
- },
- {
- "input": "Ų",
- "description": "Named entity: Uogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0172"
- ]
- ]
- },
- {
- "input": "&Uopf",
- "description": "Bad named entity: Uopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Uopf"
- ]
- ]
- },
- {
- "input": "𝕌",
- "description": "Named entity: Uopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd4c"
- ]
- ]
- },
- {
- "input": "&UpArrow",
- "description": "Bad named entity: UpArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&UpArrow"
- ]
- ]
- },
- {
- "input": "↑",
- "description": "Named entity: UpArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2191"
- ]
- ]
- },
- {
- "input": "&UpArrowBar",
- "description": "Bad named entity: UpArrowBar without a semi-colon",
- "output": [
- [
- "Character",
- "&UpArrowBar"
- ]
- ]
- },
- {
- "input": "⤒",
- "description": "Named entity: UpArrowBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2912"
- ]
- ]
- },
- {
- "input": "&UpArrowDownArrow",
- "description": "Bad named entity: UpArrowDownArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&UpArrowDownArrow"
- ]
- ]
- },
- {
- "input": "⇅",
- "description": "Named entity: UpArrowDownArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c5"
- ]
- ]
- },
- {
- "input": "&UpDownArrow",
- "description": "Bad named entity: UpDownArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&UpDownArrow"
- ]
- ]
- },
- {
- "input": "↕",
- "description": "Named entity: UpDownArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2195"
- ]
- ]
- },
- {
- "input": "&UpEquilibrium",
- "description": "Bad named entity: UpEquilibrium without a semi-colon",
- "output": [
- [
- "Character",
- "&UpEquilibrium"
- ]
- ]
- },
- {
- "input": "⥮",
- "description": "Named entity: UpEquilibrium; with a semi-colon",
- "output": [
- [
- "Character",
- "\u296e"
- ]
- ]
- },
- {
- "input": "&UpTee",
- "description": "Bad named entity: UpTee without a semi-colon",
- "output": [
- [
- "Character",
- "&UpTee"
- ]
- ]
- },
- {
- "input": "⊥",
- "description": "Named entity: UpTee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a5"
- ]
- ]
- },
- {
- "input": "&UpTeeArrow",
- "description": "Bad named entity: UpTeeArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&UpTeeArrow"
- ]
- ]
- },
- {
- "input": "↥",
- "description": "Named entity: UpTeeArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a5"
- ]
- ]
- },
- {
- "input": "&Uparrow",
- "description": "Bad named entity: Uparrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Uparrow"
- ]
- ]
- },
- {
- "input": "⇑",
- "description": "Named entity: Uparrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d1"
- ]
- ]
- },
- {
- "input": "&Updownarrow",
- "description": "Bad named entity: Updownarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&Updownarrow"
- ]
- ]
- },
- {
- "input": "⇕",
- "description": "Named entity: Updownarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d5"
- ]
- ]
- },
- {
- "input": "&UpperLeftArrow",
- "description": "Bad named entity: UpperLeftArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&UpperLeftArrow"
- ]
- ]
- },
- {
- "input": "↖",
- "description": "Named entity: UpperLeftArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2196"
- ]
- ]
- },
- {
- "input": "&UpperRightArrow",
- "description": "Bad named entity: UpperRightArrow without a semi-colon",
- "output": [
- [
- "Character",
- "&UpperRightArrow"
- ]
- ]
- },
- {
- "input": "↗",
- "description": "Named entity: UpperRightArrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2197"
- ]
- ]
- },
- {
- "input": "&Upsi",
- "description": "Bad named entity: Upsi without a semi-colon",
- "output": [
- [
- "Character",
- "&Upsi"
- ]
- ]
- },
- {
- "input": "ϒ",
- "description": "Named entity: Upsi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d2"
- ]
- ]
- },
- {
- "input": "&Upsilon",
- "description": "Bad named entity: Upsilon without a semi-colon",
- "output": [
- [
- "Character",
- "&Upsilon"
- ]
- ]
- },
- {
- "input": "Υ",
- "description": "Named entity: Upsilon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a5"
- ]
- ]
- },
- {
- "input": "&Uring",
- "description": "Bad named entity: Uring without a semi-colon",
- "output": [
- [
- "Character",
- "&Uring"
- ]
- ]
- },
- {
- "input": "Ů",
- "description": "Named entity: Uring; with a semi-colon",
- "output": [
- [
- "Character",
- "\u016e"
- ]
- ]
- },
- {
- "input": "&Uscr",
- "description": "Bad named entity: Uscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Uscr"
- ]
- ]
- },
- {
- "input": "𝒰",
- "description": "Named entity: Uscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb0"
- ]
- ]
- },
- {
- "input": "&Utilde",
- "description": "Bad named entity: Utilde without a semi-colon",
- "output": [
- [
- "Character",
- "&Utilde"
- ]
- ]
- },
- {
- "input": "Ũ",
- "description": "Named entity: Utilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0168"
- ]
- ]
- },
- {
- "input": "Ü",
- "description": "Named entity: Uuml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00dc"
- ]
- ]
- },
- {
- "input": "Ü",
- "description": "Named entity: Uuml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00dc"
- ]
- ]
- },
- {
- "input": "&VDash",
- "description": "Bad named entity: VDash without a semi-colon",
- "output": [
- [
- "Character",
- "&VDash"
- ]
- ]
- },
- {
- "input": "⊫",
- "description": "Named entity: VDash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ab"
- ]
- ]
- },
- {
- "input": "&Vbar",
- "description": "Bad named entity: Vbar without a semi-colon",
- "output": [
- [
- "Character",
- "&Vbar"
- ]
- ]
- },
- {
- "input": "⫫",
- "description": "Named entity: Vbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aeb"
- ]
- ]
- },
- {
- "input": "&Vcy",
- "description": "Bad named entity: Vcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Vcy"
- ]
- ]
- },
- {
- "input": "В",
- "description": "Named entity: Vcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0412"
- ]
- ]
- },
- {
- "input": "&Vdash",
- "description": "Bad named entity: Vdash without a semi-colon",
- "output": [
- [
- "Character",
- "&Vdash"
- ]
- ]
- },
- {
- "input": "⊩",
- "description": "Named entity: Vdash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a9"
- ]
- ]
- },
- {
- "input": "&Vdashl",
- "description": "Bad named entity: Vdashl without a semi-colon",
- "output": [
- [
- "Character",
- "&Vdashl"
- ]
- ]
- },
- {
- "input": "⫦",
- "description": "Named entity: Vdashl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ae6"
- ]
- ]
- },
- {
- "input": "&Vee",
- "description": "Bad named entity: Vee without a semi-colon",
- "output": [
- [
- "Character",
- "&Vee"
- ]
- ]
- },
- {
- "input": "⋁",
- "description": "Named entity: Vee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c1"
- ]
- ]
- },
- {
- "input": "&Verbar",
- "description": "Bad named entity: Verbar without a semi-colon",
- "output": [
- [
- "Character",
- "&Verbar"
- ]
- ]
- },
- {
- "input": "‖",
- "description": "Named entity: Verbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2016"
- ]
- ]
- },
- {
- "input": "&Vert",
- "description": "Bad named entity: Vert without a semi-colon",
- "output": [
- [
- "Character",
- "&Vert"
- ]
- ]
- },
- {
- "input": "‖",
- "description": "Named entity: Vert; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2016"
- ]
- ]
- },
- {
- "input": "&VerticalBar",
- "description": "Bad named entity: VerticalBar without a semi-colon",
- "output": [
- [
- "Character",
- "&VerticalBar"
- ]
- ]
- },
- {
- "input": "∣",
- "description": "Named entity: VerticalBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2223"
- ]
- ]
- },
- {
- "input": "&VerticalLine",
- "description": "Bad named entity: VerticalLine without a semi-colon",
- "output": [
- [
- "Character",
- "&VerticalLine"
- ]
- ]
- },
- {
- "input": "|",
- "description": "Named entity: VerticalLine; with a semi-colon",
- "output": [
- [
- "Character",
- "|"
- ]
- ]
- },
- {
- "input": "&VerticalSeparator",
- "description": "Bad named entity: VerticalSeparator without a semi-colon",
- "output": [
- [
- "Character",
- "&VerticalSeparator"
- ]
- ]
- },
- {
- "input": "❘",
- "description": "Named entity: VerticalSeparator; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2758"
- ]
- ]
- },
- {
- "input": "&VerticalTilde",
- "description": "Bad named entity: VerticalTilde without a semi-colon",
- "output": [
- [
- "Character",
- "&VerticalTilde"
- ]
- ]
- },
- {
- "input": "≀",
- "description": "Named entity: VerticalTilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2240"
- ]
- ]
- },
- {
- "input": "&VeryThinSpace",
- "description": "Bad named entity: VeryThinSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&VeryThinSpace"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: VeryThinSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200a"
- ]
- ]
- },
- {
- "input": "&Vfr",
- "description": "Bad named entity: Vfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Vfr"
- ]
- ]
- },
- {
- "input": "𝔙",
- "description": "Named entity: Vfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd19"
- ]
- ]
- },
- {
- "input": "&Vopf",
- "description": "Bad named entity: Vopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Vopf"
- ]
- ]
- },
- {
- "input": "𝕍",
- "description": "Named entity: Vopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd4d"
- ]
- ]
- },
- {
- "input": "&Vscr",
- "description": "Bad named entity: Vscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Vscr"
- ]
- ]
- },
- {
- "input": "𝒱",
- "description": "Named entity: Vscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb1"
- ]
- ]
- },
- {
- "input": "&Vvdash",
- "description": "Bad named entity: Vvdash without a semi-colon",
- "output": [
- [
- "Character",
- "&Vvdash"
- ]
- ]
- },
- {
- "input": "⊪",
- "description": "Named entity: Vvdash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22aa"
- ]
- ]
- },
- {
- "input": "&Wcirc",
- "description": "Bad named entity: Wcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&Wcirc"
- ]
- ]
- },
- {
- "input": "Ŵ",
- "description": "Named entity: Wcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0174"
- ]
- ]
- },
- {
- "input": "&Wedge",
- "description": "Bad named entity: Wedge without a semi-colon",
- "output": [
- [
- "Character",
- "&Wedge"
- ]
- ]
- },
- {
- "input": "⋀",
- "description": "Named entity: Wedge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c0"
- ]
- ]
- },
- {
- "input": "&Wfr",
- "description": "Bad named entity: Wfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Wfr"
- ]
- ]
- },
- {
- "input": "𝔚",
- "description": "Named entity: Wfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd1a"
- ]
- ]
- },
- {
- "input": "&Wopf",
- "description": "Bad named entity: Wopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Wopf"
- ]
- ]
- },
- {
- "input": "𝕎",
- "description": "Named entity: Wopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd4e"
- ]
- ]
- },
- {
- "input": "&Wscr",
- "description": "Bad named entity: Wscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Wscr"
- ]
- ]
- },
- {
- "input": "𝒲",
- "description": "Named entity: Wscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb2"
- ]
- ]
- },
- {
- "input": "&Xfr",
- "description": "Bad named entity: Xfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Xfr"
- ]
- ]
- },
- {
- "input": "𝔛",
- "description": "Named entity: Xfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd1b"
- ]
- ]
- },
- {
- "input": "&Xi",
- "description": "Bad named entity: Xi without a semi-colon",
- "output": [
- [
- "Character",
- "&Xi"
- ]
- ]
- },
- {
- "input": "Ξ",
- "description": "Named entity: Xi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u039e"
- ]
- ]
- },
- {
- "input": "&Xopf",
- "description": "Bad named entity: Xopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Xopf"
- ]
- ]
- },
- {
- "input": "𝕏",
- "description": "Named entity: Xopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd4f"
- ]
- ]
- },
- {
- "input": "&Xscr",
- "description": "Bad named entity: Xscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Xscr"
- ]
- ]
- },
- {
- "input": "𝒳",
- "description": "Named entity: Xscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb3"
- ]
- ]
- },
- {
- "input": "&YAcy",
- "description": "Bad named entity: YAcy without a semi-colon",
- "output": [
- [
- "Character",
- "&YAcy"
- ]
- ]
- },
- {
- "input": "Я",
- "description": "Named entity: YAcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u042f"
- ]
- ]
- },
- {
- "input": "&YIcy",
- "description": "Bad named entity: YIcy without a semi-colon",
- "output": [
- [
- "Character",
- "&YIcy"
- ]
- ]
- },
- {
- "input": "Ї",
- "description": "Named entity: YIcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0407"
- ]
- ]
- },
- {
- "input": "&YUcy",
- "description": "Bad named entity: YUcy without a semi-colon",
- "output": [
- [
- "Character",
- "&YUcy"
- ]
- ]
- },
- {
- "input": "Ю",
- "description": "Named entity: YUcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u042e"
- ]
- ]
- },
- {
- "input": "Ý",
- "description": "Named entity: Yacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00dd"
- ]
- ]
- },
- {
- "input": "Ý",
- "description": "Named entity: Yacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00dd"
- ]
- ]
- },
- {
- "input": "&Ycirc",
- "description": "Bad named entity: Ycirc without a semi-colon",
- "output": [
- [
- "Character",
- "&Ycirc"
- ]
- ]
- },
- {
- "input": "Ŷ",
- "description": "Named entity: Ycirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0176"
- ]
- ]
- },
- {
- "input": "&Ycy",
- "description": "Bad named entity: Ycy without a semi-colon",
- "output": [
- [
- "Character",
- "&Ycy"
- ]
- ]
- },
- {
- "input": "Ы",
- "description": "Named entity: Ycy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u042b"
- ]
- ]
- },
- {
- "input": "&Yfr",
- "description": "Bad named entity: Yfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Yfr"
- ]
- ]
- },
- {
- "input": "𝔜",
- "description": "Named entity: Yfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd1c"
- ]
- ]
- },
- {
- "input": "&Yopf",
- "description": "Bad named entity: Yopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Yopf"
- ]
- ]
- },
- {
- "input": "𝕐",
- "description": "Named entity: Yopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd50"
- ]
- ]
- },
- {
- "input": "&Yscr",
- "description": "Bad named entity: Yscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Yscr"
- ]
- ]
- },
- {
- "input": "𝒴",
- "description": "Named entity: Yscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb4"
- ]
- ]
- },
- {
- "input": "&Yuml",
- "description": "Bad named entity: Yuml without a semi-colon",
- "output": [
- [
- "Character",
- "&Yuml"
- ]
- ]
- },
- {
- "input": "Ÿ",
- "description": "Named entity: Yuml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0178"
- ]
- ]
- },
- {
- "input": "&ZHcy",
- "description": "Bad named entity: ZHcy without a semi-colon",
- "output": [
- [
- "Character",
- "&ZHcy"
- ]
- ]
- },
- {
- "input": "Ж",
- "description": "Named entity: ZHcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0416"
- ]
- ]
- },
- {
- "input": "&Zacute",
- "description": "Bad named entity: Zacute without a semi-colon",
- "output": [
- [
- "Character",
- "&Zacute"
- ]
- ]
- },
- {
- "input": "Ź",
- "description": "Named entity: Zacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0179"
- ]
- ]
- },
- {
- "input": "&Zcaron",
- "description": "Bad named entity: Zcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&Zcaron"
- ]
- ]
- },
- {
- "input": "Ž",
- "description": "Named entity: Zcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u017d"
- ]
- ]
- },
- {
- "input": "&Zcy",
- "description": "Bad named entity: Zcy without a semi-colon",
- "output": [
- [
- "Character",
- "&Zcy"
- ]
- ]
- },
- {
- "input": "З",
- "description": "Named entity: Zcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0417"
- ]
- ]
- },
- {
- "input": "&Zdot",
- "description": "Bad named entity: Zdot without a semi-colon",
- "output": [
- [
- "Character",
- "&Zdot"
- ]
- ]
- },
- {
- "input": "Ż",
- "description": "Named entity: Zdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u017b"
- ]
- ]
- },
- {
- "input": "&ZeroWidthSpace",
- "description": "Bad named entity: ZeroWidthSpace without a semi-colon",
- "output": [
- [
- "Character",
- "&ZeroWidthSpace"
- ]
- ]
- },
- {
- "input": "​",
- "description": "Named entity: ZeroWidthSpace; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200b"
- ]
- ]
- },
- {
- "input": "&Zeta",
- "description": "Bad named entity: Zeta without a semi-colon",
- "output": [
- [
- "Character",
- "&Zeta"
- ]
- ]
- },
- {
- "input": "Ζ",
- "description": "Named entity: Zeta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0396"
- ]
- ]
- },
- {
- "input": "&Zfr",
- "description": "Bad named entity: Zfr without a semi-colon",
- "output": [
- [
- "Character",
- "&Zfr"
- ]
- ]
- },
- {
- "input": "ℨ",
- "description": "Named entity: Zfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2128"
- ]
- ]
- },
- {
- "input": "&Zopf",
- "description": "Bad named entity: Zopf without a semi-colon",
- "output": [
- [
- "Character",
- "&Zopf"
- ]
- ]
- },
- {
- "input": "ℤ",
- "description": "Named entity: Zopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2124"
- ]
- ]
- },
- {
- "input": "&Zscr",
- "description": "Bad named entity: Zscr without a semi-colon",
- "output": [
- [
- "Character",
- "&Zscr"
- ]
- ]
- },
- {
- "input": "𝒵",
- "description": "Named entity: Zscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb5"
- ]
- ]
- },
- {
- "input": "á",
- "description": "Named entity: aacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e1"
- ]
- ]
- },
- {
- "input": "á",
- "description": "Named entity: aacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e1"
- ]
- ]
- },
- {
- "input": "&abreve",
- "description": "Bad named entity: abreve without a semi-colon",
- "output": [
- [
- "Character",
- "&abreve"
- ]
- ]
- },
- {
- "input": "ă",
- "description": "Named entity: abreve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0103"
- ]
- ]
- },
- {
- "input": "&ac",
- "description": "Bad named entity: ac without a semi-colon",
- "output": [
- [
- "Character",
- "&ac"
- ]
- ]
- },
- {
- "input": "∾",
- "description": "Named entity: ac; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223e"
- ]
- ]
- },
- {
- "input": "&acE",
- "description": "Bad named entity: acE without a semi-colon",
- "output": [
- [
- "Character",
- "&acE"
- ]
- ]
- },
- {
- "input": "∾̳",
- "description": "Named entity: acE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223e\u0333"
- ]
- ]
- },
- {
- "input": "&acd",
- "description": "Bad named entity: acd without a semi-colon",
- "output": [
- [
- "Character",
- "&acd"
- ]
- ]
- },
- {
- "input": "∿",
- "description": "Named entity: acd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223f"
- ]
- ]
- },
- {
- "input": "â",
- "description": "Named entity: acirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e2"
- ]
- ]
- },
- {
- "input": "â",
- "description": "Named entity: acirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e2"
- ]
- ]
- },
- {
- "input": "´",
- "description": "Named entity: acute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b4"
- ]
- ]
- },
- {
- "input": "´",
- "description": "Named entity: acute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b4"
- ]
- ]
- },
- {
- "input": "&acy",
- "description": "Bad named entity: acy without a semi-colon",
- "output": [
- [
- "Character",
- "&acy"
- ]
- ]
- },
- {
- "input": "а",
- "description": "Named entity: acy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0430"
- ]
- ]
- },
- {
- "input": "æ",
- "description": "Named entity: aelig without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e6"
- ]
- ]
- },
- {
- "input": "æ",
- "description": "Named entity: aelig; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e6"
- ]
- ]
- },
- {
- "input": "&af",
- "description": "Bad named entity: af without a semi-colon",
- "output": [
- [
- "Character",
- "&af"
- ]
- ]
- },
- {
- "input": "⁡",
- "description": "Named entity: af; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2061"
- ]
- ]
- },
- {
- "input": "&afr",
- "description": "Bad named entity: afr without a semi-colon",
- "output": [
- [
- "Character",
- "&afr"
- ]
- ]
- },
- {
- "input": "𝔞",
- "description": "Named entity: afr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd1e"
- ]
- ]
- },
- {
- "input": "à",
- "description": "Named entity: agrave without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e0"
- ]
- ]
- },
- {
- "input": "à",
- "description": "Named entity: agrave; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e0"
- ]
- ]
- },
- {
- "input": "&alefsym",
- "description": "Bad named entity: alefsym without a semi-colon",
- "output": [
- [
- "Character",
- "&alefsym"
- ]
- ]
- },
- {
- "input": "ℵ",
- "description": "Named entity: alefsym; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2135"
- ]
- ]
- },
- {
- "input": "&aleph",
- "description": "Bad named entity: aleph without a semi-colon",
- "output": [
- [
- "Character",
- "&aleph"
- ]
- ]
- },
- {
- "input": "ℵ",
- "description": "Named entity: aleph; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2135"
- ]
- ]
- },
- {
- "input": "&alpha",
- "description": "Bad named entity: alpha without a semi-colon",
- "output": [
- [
- "Character",
- "&alpha"
- ]
- ]
- },
- {
- "input": "α",
- "description": "Named entity: alpha; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b1"
- ]
- ]
- },
- {
- "input": "&amacr",
- "description": "Bad named entity: amacr without a semi-colon",
- "output": [
- [
- "Character",
- "&amacr"
- ]
- ]
- },
- {
- "input": "ā",
- "description": "Named entity: amacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0101"
- ]
- ]
- },
- {
- "input": "&amalg",
- "description": "Bad named entity: amalg without a semi-colon",
- "output": [
- [
- "Character",
- "&amalg"
- ]
- ]
- },
- {
- "input": "⨿",
- "description": "Named entity: amalg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a3f"
- ]
- ]
- },
- {
- "input": "&",
- "description": "Named entity: amp without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "&"
- ]
- ]
- },
- {
- "input": "&",
- "description": "Named entity: amp; with a semi-colon",
- "output": [
- [
- "Character",
- "&"
- ]
- ]
- },
- {
- "input": "&and",
- "description": "Bad named entity: and without a semi-colon",
- "output": [
- [
- "Character",
- "&and"
- ]
- ]
- },
- {
- "input": "∧",
- "description": "Named entity: and; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2227"
- ]
- ]
- },
- {
- "input": "&andand",
- "description": "Bad named entity: andand without a semi-colon",
- "output": [
- [
- "Character",
- "&andand"
- ]
- ]
- },
- {
- "input": "⩕",
- "description": "Named entity: andand; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a55"
- ]
- ]
- },
- {
- "input": "&andd",
- "description": "Bad named entity: andd without a semi-colon",
- "output": [
- [
- "Character",
- "&andd"
- ]
- ]
- },
- {
- "input": "⩜",
- "description": "Named entity: andd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a5c"
- ]
- ]
- },
- {
- "input": "&andslope",
- "description": "Bad named entity: andslope without a semi-colon",
- "output": [
- [
- "Character",
- "&andslope"
- ]
- ]
- },
- {
- "input": "⩘",
- "description": "Named entity: andslope; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a58"
- ]
- ]
- },
- {
- "input": "&andv",
- "description": "Bad named entity: andv without a semi-colon",
- "output": [
- [
- "Character",
- "&andv"
- ]
- ]
- },
- {
- "input": "⩚",
- "description": "Named entity: andv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a5a"
- ]
- ]
- },
- {
- "input": "&ang",
- "description": "Bad named entity: ang without a semi-colon",
- "output": [
- [
- "Character",
- "&ang"
- ]
- ]
- },
- {
- "input": "∠",
- "description": "Named entity: ang; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2220"
- ]
- ]
- },
- {
- "input": "&ange",
- "description": "Bad named entity: ange without a semi-colon",
- "output": [
- [
- "Character",
- "&ange"
- ]
- ]
- },
- {
- "input": "⦤",
- "description": "Named entity: ange; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29a4"
- ]
- ]
- },
- {
- "input": "&angle",
- "description": "Bad named entity: angle without a semi-colon",
- "output": [
- [
- "Character",
- "&angle"
- ]
- ]
- },
- {
- "input": "∠",
- "description": "Named entity: angle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2220"
- ]
- ]
- },
- {
- "input": "&angmsd",
- "description": "Bad named entity: angmsd without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsd"
- ]
- ]
- },
- {
- "input": "∡",
- "description": "Named entity: angmsd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2221"
- ]
- ]
- },
- {
- "input": "&angmsdaa",
- "description": "Bad named entity: angmsdaa without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsdaa"
- ]
- ]
- },
- {
- "input": "⦨",
- "description": "Named entity: angmsdaa; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29a8"
- ]
- ]
- },
- {
- "input": "&angmsdab",
- "description": "Bad named entity: angmsdab without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsdab"
- ]
- ]
- },
- {
- "input": "⦩",
- "description": "Named entity: angmsdab; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29a9"
- ]
- ]
- },
- {
- "input": "&angmsdac",
- "description": "Bad named entity: angmsdac without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsdac"
- ]
- ]
- },
- {
- "input": "⦪",
- "description": "Named entity: angmsdac; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29aa"
- ]
- ]
- },
- {
- "input": "&angmsdad",
- "description": "Bad named entity: angmsdad without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsdad"
- ]
- ]
- },
- {
- "input": "⦫",
- "description": "Named entity: angmsdad; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29ab"
- ]
- ]
- },
- {
- "input": "&angmsdae",
- "description": "Bad named entity: angmsdae without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsdae"
- ]
- ]
- },
- {
- "input": "⦬",
- "description": "Named entity: angmsdae; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29ac"
- ]
- ]
- },
- {
- "input": "&angmsdaf",
- "description": "Bad named entity: angmsdaf without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsdaf"
- ]
- ]
- },
- {
- "input": "⦭",
- "description": "Named entity: angmsdaf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29ad"
- ]
- ]
- },
- {
- "input": "&angmsdag",
- "description": "Bad named entity: angmsdag without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsdag"
- ]
- ]
- },
- {
- "input": "⦮",
- "description": "Named entity: angmsdag; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29ae"
- ]
- ]
- },
- {
- "input": "&angmsdah",
- "description": "Bad named entity: angmsdah without a semi-colon",
- "output": [
- [
- "Character",
- "&angmsdah"
- ]
- ]
- },
- {
- "input": "⦯",
- "description": "Named entity: angmsdah; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29af"
- ]
- ]
- },
- {
- "input": "&angrt",
- "description": "Bad named entity: angrt without a semi-colon",
- "output": [
- [
- "Character",
- "&angrt"
- ]
- ]
- },
- {
- "input": "∟",
- "description": "Named entity: angrt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221f"
- ]
- ]
- },
- {
- "input": "&angrtvb",
- "description": "Bad named entity: angrtvb without a semi-colon",
- "output": [
- [
- "Character",
- "&angrtvb"
- ]
- ]
- },
- {
- "input": "⊾",
- "description": "Named entity: angrtvb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22be"
- ]
- ]
- },
- {
- "input": "&angrtvbd",
- "description": "Bad named entity: angrtvbd without a semi-colon",
- "output": [
- [
- "Character",
- "&angrtvbd"
- ]
- ]
- },
- {
- "input": "⦝",
- "description": "Named entity: angrtvbd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u299d"
- ]
- ]
- },
- {
- "input": "&angsph",
- "description": "Bad named entity: angsph without a semi-colon",
- "output": [
- [
- "Character",
- "&angsph"
- ]
- ]
- },
- {
- "input": "∢",
- "description": "Named entity: angsph; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2222"
- ]
- ]
- },
- {
- "input": "&angst",
- "description": "Bad named entity: angst without a semi-colon",
- "output": [
- [
- "Character",
- "&angst"
- ]
- ]
- },
- {
- "input": "Å",
- "description": "Named entity: angst; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00c5"
- ]
- ]
- },
- {
- "input": "&angzarr",
- "description": "Bad named entity: angzarr without a semi-colon",
- "output": [
- [
- "Character",
- "&angzarr"
- ]
- ]
- },
- {
- "input": "⍼",
- "description": "Named entity: angzarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u237c"
- ]
- ]
- },
- {
- "input": "&aogon",
- "description": "Bad named entity: aogon without a semi-colon",
- "output": [
- [
- "Character",
- "&aogon"
- ]
- ]
- },
- {
- "input": "ą",
- "description": "Named entity: aogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0105"
- ]
- ]
- },
- {
- "input": "&aopf",
- "description": "Bad named entity: aopf without a semi-colon",
- "output": [
- [
- "Character",
- "&aopf"
- ]
- ]
- },
- {
- "input": "𝕒",
- "description": "Named entity: aopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd52"
- ]
- ]
- },
- {
- "input": "&ap",
- "description": "Bad named entity: ap without a semi-colon",
- "output": [
- [
- "Character",
- "&ap"
- ]
- ]
- },
- {
- "input": "≈",
- "description": "Named entity: ap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2248"
- ]
- ]
- },
- {
- "input": "&apE",
- "description": "Bad named entity: apE without a semi-colon",
- "output": [
- [
- "Character",
- "&apE"
- ]
- ]
- },
- {
- "input": "⩰",
- "description": "Named entity: apE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a70"
- ]
- ]
- },
- {
- "input": "&apacir",
- "description": "Bad named entity: apacir without a semi-colon",
- "output": [
- [
- "Character",
- "&apacir"
- ]
- ]
- },
- {
- "input": "⩯",
- "description": "Named entity: apacir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a6f"
- ]
- ]
- },
- {
- "input": "&ape",
- "description": "Bad named entity: ape without a semi-colon",
- "output": [
- [
- "Character",
- "&ape"
- ]
- ]
- },
- {
- "input": "≊",
- "description": "Named entity: ape; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224a"
- ]
- ]
- },
- {
- "input": "&apid",
- "description": "Bad named entity: apid without a semi-colon",
- "output": [
- [
- "Character",
- "&apid"
- ]
- ]
- },
- {
- "input": "≋",
- "description": "Named entity: apid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224b"
- ]
- ]
- },
- {
- "input": "&apos",
- "description": "Bad named entity: apos without a semi-colon",
- "output": [
- [
- "Character",
- "&apos"
- ]
- ]
- },
- {
- "input": "'",
- "description": "Named entity: apos; with a semi-colon",
- "output": [
- [
- "Character",
- "'"
- ]
- ]
- },
- {
- "input": "&approx",
- "description": "Bad named entity: approx without a semi-colon",
- "output": [
- [
- "Character",
- "&approx"
- ]
- ]
- },
- {
- "input": "≈",
- "description": "Named entity: approx; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2248"
- ]
- ]
- },
- {
- "input": "&approxeq",
- "description": "Bad named entity: approxeq without a semi-colon",
- "output": [
- [
- "Character",
- "&approxeq"
- ]
- ]
- },
- {
- "input": "≊",
- "description": "Named entity: approxeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224a"
- ]
- ]
- },
- {
- "input": "å",
- "description": "Named entity: aring without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e5"
- ]
- ]
- },
- {
- "input": "å",
- "description": "Named entity: aring; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e5"
- ]
- ]
- },
- {
- "input": "&ascr",
- "description": "Bad named entity: ascr without a semi-colon",
- "output": [
- [
- "Character",
- "&ascr"
- ]
- ]
- },
- {
- "input": "𝒶",
- "description": "Named entity: ascr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb6"
- ]
- ]
- },
- {
- "input": "&ast",
- "description": "Bad named entity: ast without a semi-colon",
- "output": [
- [
- "Character",
- "&ast"
- ]
- ]
- },
- {
- "input": "*",
- "description": "Named entity: ast; with a semi-colon",
- "output": [
- [
- "Character",
- "*"
- ]
- ]
- },
- {
- "input": "&asymp",
- "description": "Bad named entity: asymp without a semi-colon",
- "output": [
- [
- "Character",
- "&asymp"
- ]
- ]
- },
- {
- "input": "≈",
- "description": "Named entity: asymp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2248"
- ]
- ]
- },
- {
- "input": "&asympeq",
- "description": "Bad named entity: asympeq without a semi-colon",
- "output": [
- [
- "Character",
- "&asympeq"
- ]
- ]
- },
- {
- "input": "≍",
- "description": "Named entity: asympeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224d"
- ]
- ]
- },
- {
- "input": "ã",
- "description": "Named entity: atilde without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e3"
- ]
- ]
- },
- {
- "input": "ã",
- "description": "Named entity: atilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e3"
- ]
- ]
- },
- {
- "input": "ä",
- "description": "Named entity: auml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e4"
- ]
- ]
- },
- {
- "input": "ä",
- "description": "Named entity: auml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e4"
- ]
- ]
- },
- {
- "input": "&awconint",
- "description": "Bad named entity: awconint without a semi-colon",
- "output": [
- [
- "Character",
- "&awconint"
- ]
- ]
- },
- {
- "input": "∳",
- "description": "Named entity: awconint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2233"
- ]
- ]
- },
- {
- "input": "&awint",
- "description": "Bad named entity: awint without a semi-colon",
- "output": [
- [
- "Character",
- "&awint"
- ]
- ]
- },
- {
- "input": "⨑",
- "description": "Named entity: awint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a11"
- ]
- ]
- },
- {
- "input": "&bNot",
- "description": "Bad named entity: bNot without a semi-colon",
- "output": [
- [
- "Character",
- "&bNot"
- ]
- ]
- },
- {
- "input": "⫭",
- "description": "Named entity: bNot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aed"
- ]
- ]
- },
- {
- "input": "&backcong",
- "description": "Bad named entity: backcong without a semi-colon",
- "output": [
- [
- "Character",
- "&backcong"
- ]
- ]
- },
- {
- "input": "≌",
- "description": "Named entity: backcong; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224c"
- ]
- ]
- },
- {
- "input": "&backepsilon",
- "description": "Bad named entity: backepsilon without a semi-colon",
- "output": [
- [
- "Character",
- "&backepsilon"
- ]
- ]
- },
- {
- "input": "϶",
- "description": "Named entity: backepsilon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f6"
- ]
- ]
- },
- {
- "input": "&backprime",
- "description": "Bad named entity: backprime without a semi-colon",
- "output": [
- [
- "Character",
- "&backprime"
- ]
- ]
- },
- {
- "input": "‵",
- "description": "Named entity: backprime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2035"
- ]
- ]
- },
- {
- "input": "&backsim",
- "description": "Bad named entity: backsim without a semi-colon",
- "output": [
- [
- "Character",
- "&backsim"
- ]
- ]
- },
- {
- "input": "∽",
- "description": "Named entity: backsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223d"
- ]
- ]
- },
- {
- "input": "&backsimeq",
- "description": "Bad named entity: backsimeq without a semi-colon",
- "output": [
- [
- "Character",
- "&backsimeq"
- ]
- ]
- },
- {
- "input": "⋍",
- "description": "Named entity: backsimeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22cd"
- ]
- ]
- },
- {
- "input": "&barvee",
- "description": "Bad named entity: barvee without a semi-colon",
- "output": [
- [
- "Character",
- "&barvee"
- ]
- ]
- },
- {
- "input": "⊽",
- "description": "Named entity: barvee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22bd"
- ]
- ]
- },
- {
- "input": "&barwed",
- "description": "Bad named entity: barwed without a semi-colon",
- "output": [
- [
- "Character",
- "&barwed"
- ]
- ]
- },
- {
- "input": "⌅",
- "description": "Named entity: barwed; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2305"
- ]
- ]
- },
- {
- "input": "&barwedge",
- "description": "Bad named entity: barwedge without a semi-colon",
- "output": [
- [
- "Character",
- "&barwedge"
- ]
- ]
- },
- {
- "input": "⌅",
- "description": "Named entity: barwedge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2305"
- ]
- ]
- },
- {
- "input": "&bbrk",
- "description": "Bad named entity: bbrk without a semi-colon",
- "output": [
- [
- "Character",
- "&bbrk"
- ]
- ]
- },
- {
- "input": "⎵",
- "description": "Named entity: bbrk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b5"
- ]
- ]
- },
- {
- "input": "&bbrktbrk",
- "description": "Bad named entity: bbrktbrk without a semi-colon",
- "output": [
- [
- "Character",
- "&bbrktbrk"
- ]
- ]
- },
- {
- "input": "⎶",
- "description": "Named entity: bbrktbrk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b6"
- ]
- ]
- },
- {
- "input": "&bcong",
- "description": "Bad named entity: bcong without a semi-colon",
- "output": [
- [
- "Character",
- "&bcong"
- ]
- ]
- },
- {
- "input": "≌",
- "description": "Named entity: bcong; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224c"
- ]
- ]
- },
- {
- "input": "&bcy",
- "description": "Bad named entity: bcy without a semi-colon",
- "output": [
- [
- "Character",
- "&bcy"
- ]
- ]
- },
- {
- "input": "б",
- "description": "Named entity: bcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0431"
- ]
- ]
- },
- {
- "input": "&bdquo",
- "description": "Bad named entity: bdquo without a semi-colon",
- "output": [
- [
- "Character",
- "&bdquo"
- ]
- ]
- },
- {
- "input": "„",
- "description": "Named entity: bdquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201e"
- ]
- ]
- },
- {
- "input": "&becaus",
- "description": "Bad named entity: becaus without a semi-colon",
- "output": [
- [
- "Character",
- "&becaus"
- ]
- ]
- },
- {
- "input": "∵",
- "description": "Named entity: becaus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2235"
- ]
- ]
- },
- {
- "input": "&because",
- "description": "Bad named entity: because without a semi-colon",
- "output": [
- [
- "Character",
- "&because"
- ]
- ]
- },
- {
- "input": "∵",
- "description": "Named entity: because; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2235"
- ]
- ]
- },
- {
- "input": "&bemptyv",
- "description": "Bad named entity: bemptyv without a semi-colon",
- "output": [
- [
- "Character",
- "&bemptyv"
- ]
- ]
- },
- {
- "input": "⦰",
- "description": "Named entity: bemptyv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b0"
- ]
- ]
- },
- {
- "input": "&bepsi",
- "description": "Bad named entity: bepsi without a semi-colon",
- "output": [
- [
- "Character",
- "&bepsi"
- ]
- ]
- },
- {
- "input": "϶",
- "description": "Named entity: bepsi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f6"
- ]
- ]
- },
- {
- "input": "&bernou",
- "description": "Bad named entity: bernou without a semi-colon",
- "output": [
- [
- "Character",
- "&bernou"
- ]
- ]
- },
- {
- "input": "ℬ",
- "description": "Named entity: bernou; with a semi-colon",
- "output": [
- [
- "Character",
- "\u212c"
- ]
- ]
- },
- {
- "input": "&beta",
- "description": "Bad named entity: beta without a semi-colon",
- "output": [
- [
- "Character",
- "&beta"
- ]
- ]
- },
- {
- "input": "β",
- "description": "Named entity: beta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b2"
- ]
- ]
- },
- {
- "input": "&beth",
- "description": "Bad named entity: beth without a semi-colon",
- "output": [
- [
- "Character",
- "&beth"
- ]
- ]
- },
- {
- "input": "ℶ",
- "description": "Named entity: beth; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2136"
- ]
- ]
- },
- {
- "input": "&between",
- "description": "Bad named entity: between without a semi-colon",
- "output": [
- [
- "Character",
- "&between"
- ]
- ]
- },
- {
- "input": "≬",
- "description": "Named entity: between; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226c"
- ]
- ]
- },
- {
- "input": "&bfr",
- "description": "Bad named entity: bfr without a semi-colon",
- "output": [
- [
- "Character",
- "&bfr"
- ]
- ]
- },
- {
- "input": "𝔟",
- "description": "Named entity: bfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd1f"
- ]
- ]
- },
- {
- "input": "&bigcap",
- "description": "Bad named entity: bigcap without a semi-colon",
- "output": [
- [
- "Character",
- "&bigcap"
- ]
- ]
- },
- {
- "input": "⋂",
- "description": "Named entity: bigcap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c2"
- ]
- ]
- },
- {
- "input": "&bigcirc",
- "description": "Bad named entity: bigcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&bigcirc"
- ]
- ]
- },
- {
- "input": "◯",
- "description": "Named entity: bigcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25ef"
- ]
- ]
- },
- {
- "input": "&bigcup",
- "description": "Bad named entity: bigcup without a semi-colon",
- "output": [
- [
- "Character",
- "&bigcup"
- ]
- ]
- },
- {
- "input": "⋃",
- "description": "Named entity: bigcup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c3"
- ]
- ]
- },
- {
- "input": "&bigodot",
- "description": "Bad named entity: bigodot without a semi-colon",
- "output": [
- [
- "Character",
- "&bigodot"
- ]
- ]
- },
- {
- "input": "⨀",
- "description": "Named entity: bigodot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a00"
- ]
- ]
- },
- {
- "input": "&bigoplus",
- "description": "Bad named entity: bigoplus without a semi-colon",
- "output": [
- [
- "Character",
- "&bigoplus"
- ]
- ]
- },
- {
- "input": "⨁",
- "description": "Named entity: bigoplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a01"
- ]
- ]
- },
- {
- "input": "&bigotimes",
- "description": "Bad named entity: bigotimes without a semi-colon",
- "output": [
- [
- "Character",
- "&bigotimes"
- ]
- ]
- },
- {
- "input": "⨂",
- "description": "Named entity: bigotimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a02"
- ]
- ]
- },
- {
- "input": "&bigsqcup",
- "description": "Bad named entity: bigsqcup without a semi-colon",
- "output": [
- [
- "Character",
- "&bigsqcup"
- ]
- ]
- },
- {
- "input": "⨆",
- "description": "Named entity: bigsqcup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a06"
- ]
- ]
- },
- {
- "input": "&bigstar",
- "description": "Bad named entity: bigstar without a semi-colon",
- "output": [
- [
- "Character",
- "&bigstar"
- ]
- ]
- },
- {
- "input": "★",
- "description": "Named entity: bigstar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2605"
- ]
- ]
- },
- {
- "input": "&bigtriangledown",
- "description": "Bad named entity: bigtriangledown without a semi-colon",
- "output": [
- [
- "Character",
- "&bigtriangledown"
- ]
- ]
- },
- {
- "input": "▽",
- "description": "Named entity: bigtriangledown; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25bd"
- ]
- ]
- },
- {
- "input": "&bigtriangleup",
- "description": "Bad named entity: bigtriangleup without a semi-colon",
- "output": [
- [
- "Character",
- "&bigtriangleup"
- ]
- ]
- },
- {
- "input": "△",
- "description": "Named entity: bigtriangleup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b3"
- ]
- ]
- },
- {
- "input": "&biguplus",
- "description": "Bad named entity: biguplus without a semi-colon",
- "output": [
- [
- "Character",
- "&biguplus"
- ]
- ]
- },
- {
- "input": "⨄",
- "description": "Named entity: biguplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a04"
- ]
- ]
- },
- {
- "input": "&bigvee",
- "description": "Bad named entity: bigvee without a semi-colon",
- "output": [
- [
- "Character",
- "&bigvee"
- ]
- ]
- },
- {
- "input": "⋁",
- "description": "Named entity: bigvee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c1"
- ]
- ]
- },
- {
- "input": "&bigwedge",
- "description": "Bad named entity: bigwedge without a semi-colon",
- "output": [
- [
- "Character",
- "&bigwedge"
- ]
- ]
- },
- {
- "input": "⋀",
- "description": "Named entity: bigwedge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c0"
- ]
- ]
- },
- {
- "input": "&bkarow",
- "description": "Bad named entity: bkarow without a semi-colon",
- "output": [
- [
- "Character",
- "&bkarow"
- ]
- ]
- },
- {
- "input": "⤍",
- "description": "Named entity: bkarow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u290d"
- ]
- ]
- },
- {
- "input": "&blacklozenge",
- "description": "Bad named entity: blacklozenge without a semi-colon",
- "output": [
- [
- "Character",
- "&blacklozenge"
- ]
- ]
- },
- {
- "input": "⧫",
- "description": "Named entity: blacklozenge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29eb"
- ]
- ]
- },
- {
- "input": "&blacksquare",
- "description": "Bad named entity: blacksquare without a semi-colon",
- "output": [
- [
- "Character",
- "&blacksquare"
- ]
- ]
- },
- {
- "input": "▪",
- "description": "Named entity: blacksquare; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25aa"
- ]
- ]
- },
- {
- "input": "&blacktriangle",
- "description": "Bad named entity: blacktriangle without a semi-colon",
- "output": [
- [
- "Character",
- "&blacktriangle"
- ]
- ]
- },
- {
- "input": "▴",
- "description": "Named entity: blacktriangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b4"
- ]
- ]
- },
- {
- "input": "&blacktriangledown",
- "description": "Bad named entity: blacktriangledown without a semi-colon",
- "output": [
- [
- "Character",
- "&blacktriangledown"
- ]
- ]
- },
- {
- "input": "▾",
- "description": "Named entity: blacktriangledown; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25be"
- ]
- ]
- },
- {
- "input": "&blacktriangleleft",
- "description": "Bad named entity: blacktriangleleft without a semi-colon",
- "output": [
- [
- "Character",
- "&blacktriangleleft"
- ]
- ]
- },
- {
- "input": "◂",
- "description": "Named entity: blacktriangleleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25c2"
- ]
- ]
- },
- {
- "input": "&blacktriangleright",
- "description": "Bad named entity: blacktriangleright without a semi-colon",
- "output": [
- [
- "Character",
- "&blacktriangleright"
- ]
- ]
- },
- {
- "input": "▸",
- "description": "Named entity: blacktriangleright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b8"
- ]
- ]
- },
- {
- "input": "&blank",
- "description": "Bad named entity: blank without a semi-colon",
- "output": [
- [
- "Character",
- "&blank"
- ]
- ]
- },
- {
- "input": "␣",
- "description": "Named entity: blank; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2423"
- ]
- ]
- },
- {
- "input": "&blk12",
- "description": "Bad named entity: blk12 without a semi-colon",
- "output": [
- [
- "Character",
- "&blk12"
- ]
- ]
- },
- {
- "input": "▒",
- "description": "Named entity: blk12; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2592"
- ]
- ]
- },
- {
- "input": "&blk14",
- "description": "Bad named entity: blk14 without a semi-colon",
- "output": [
- [
- "Character",
- "&blk14"
- ]
- ]
- },
- {
- "input": "░",
- "description": "Named entity: blk14; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2591"
- ]
- ]
- },
- {
- "input": "&blk34",
- "description": "Bad named entity: blk34 without a semi-colon",
- "output": [
- [
- "Character",
- "&blk34"
- ]
- ]
- },
- {
- "input": "▓",
- "description": "Named entity: blk34; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2593"
- ]
- ]
- },
- {
- "input": "&block",
- "description": "Bad named entity: block without a semi-colon",
- "output": [
- [
- "Character",
- "&block"
- ]
- ]
- },
- {
- "input": "█",
- "description": "Named entity: block; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2588"
- ]
- ]
- },
- {
- "input": "&bne",
- "description": "Bad named entity: bne without a semi-colon",
- "output": [
- [
- "Character",
- "&bne"
- ]
- ]
- },
- {
- "input": "=⃥",
- "description": "Named entity: bne; with a semi-colon",
- "output": [
- [
- "Character",
- "=\u20e5"
- ]
- ]
- },
- {
- "input": "&bnequiv",
- "description": "Bad named entity: bnequiv without a semi-colon",
- "output": [
- [
- "Character",
- "&bnequiv"
- ]
- ]
- },
- {
- "input": "≡⃥",
- "description": "Named entity: bnequiv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2261\u20e5"
- ]
- ]
- },
- {
- "input": "&bnot",
- "description": "Bad named entity: bnot without a semi-colon",
- "output": [
- [
- "Character",
- "&bnot"
- ]
- ]
- },
- {
- "input": "⌐",
- "description": "Named entity: bnot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2310"
- ]
- ]
- },
- {
- "input": "&bopf",
- "description": "Bad named entity: bopf without a semi-colon",
- "output": [
- [
- "Character",
- "&bopf"
- ]
- ]
- },
- {
- "input": "𝕓",
- "description": "Named entity: bopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd53"
- ]
- ]
- },
- {
- "input": "&bot",
- "description": "Bad named entity: bot without a semi-colon",
- "output": [
- [
- "Character",
- "&bot"
- ]
- ]
- },
- {
- "input": "⊥",
- "description": "Named entity: bot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a5"
- ]
- ]
- },
- {
- "input": "&bottom",
- "description": "Bad named entity: bottom without a semi-colon",
- "output": [
- [
- "Character",
- "&bottom"
- ]
- ]
- },
- {
- "input": "⊥",
- "description": "Named entity: bottom; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a5"
- ]
- ]
- },
- {
- "input": "&bowtie",
- "description": "Bad named entity: bowtie without a semi-colon",
- "output": [
- [
- "Character",
- "&bowtie"
- ]
- ]
- },
- {
- "input": "⋈",
- "description": "Named entity: bowtie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c8"
- ]
- ]
- },
- {
- "input": "&boxDL",
- "description": "Bad named entity: boxDL without a semi-colon",
- "output": [
- [
- "Character",
- "&boxDL"
- ]
- ]
- },
- {
- "input": "╗",
- "description": "Named entity: boxDL; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2557"
- ]
- ]
- },
- {
- "input": "&boxDR",
- "description": "Bad named entity: boxDR without a semi-colon",
- "output": [
- [
- "Character",
- "&boxDR"
- ]
- ]
- },
- {
- "input": "╔",
- "description": "Named entity: boxDR; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2554"
- ]
- ]
- },
- {
- "input": "&boxDl",
- "description": "Bad named entity: boxDl without a semi-colon",
- "output": [
- [
- "Character",
- "&boxDl"
- ]
- ]
- },
- {
- "input": "╖",
- "description": "Named entity: boxDl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2556"
- ]
- ]
- },
- {
- "input": "&boxDr",
- "description": "Bad named entity: boxDr without a semi-colon",
- "output": [
- [
- "Character",
- "&boxDr"
- ]
- ]
- },
- {
- "input": "╓",
- "description": "Named entity: boxDr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2553"
- ]
- ]
- },
- {
- "input": "&boxH",
- "description": "Bad named entity: boxH without a semi-colon",
- "output": [
- [
- "Character",
- "&boxH"
- ]
- ]
- },
- {
- "input": "═",
- "description": "Named entity: boxH; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2550"
- ]
- ]
- },
- {
- "input": "&boxHD",
- "description": "Bad named entity: boxHD without a semi-colon",
- "output": [
- [
- "Character",
- "&boxHD"
- ]
- ]
- },
- {
- "input": "╦",
- "description": "Named entity: boxHD; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2566"
- ]
- ]
- },
- {
- "input": "&boxHU",
- "description": "Bad named entity: boxHU without a semi-colon",
- "output": [
- [
- "Character",
- "&boxHU"
- ]
- ]
- },
- {
- "input": "╩",
- "description": "Named entity: boxHU; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2569"
- ]
- ]
- },
- {
- "input": "&boxHd",
- "description": "Bad named entity: boxHd without a semi-colon",
- "output": [
- [
- "Character",
- "&boxHd"
- ]
- ]
- },
- {
- "input": "╤",
- "description": "Named entity: boxHd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2564"
- ]
- ]
- },
- {
- "input": "&boxHu",
- "description": "Bad named entity: boxHu without a semi-colon",
- "output": [
- [
- "Character",
- "&boxHu"
- ]
- ]
- },
- {
- "input": "╧",
- "description": "Named entity: boxHu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2567"
- ]
- ]
- },
- {
- "input": "&boxUL",
- "description": "Bad named entity: boxUL without a semi-colon",
- "output": [
- [
- "Character",
- "&boxUL"
- ]
- ]
- },
- {
- "input": "╝",
- "description": "Named entity: boxUL; with a semi-colon",
- "output": [
- [
- "Character",
- "\u255d"
- ]
- ]
- },
- {
- "input": "&boxUR",
- "description": "Bad named entity: boxUR without a semi-colon",
- "output": [
- [
- "Character",
- "&boxUR"
- ]
- ]
- },
- {
- "input": "╚",
- "description": "Named entity: boxUR; with a semi-colon",
- "output": [
- [
- "Character",
- "\u255a"
- ]
- ]
- },
- {
- "input": "&boxUl",
- "description": "Bad named entity: boxUl without a semi-colon",
- "output": [
- [
- "Character",
- "&boxUl"
- ]
- ]
- },
- {
- "input": "╜",
- "description": "Named entity: boxUl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u255c"
- ]
- ]
- },
- {
- "input": "&boxUr",
- "description": "Bad named entity: boxUr without a semi-colon",
- "output": [
- [
- "Character",
- "&boxUr"
- ]
- ]
- },
- {
- "input": "╙",
- "description": "Named entity: boxUr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2559"
- ]
- ]
- },
- {
- "input": "&boxV",
- "description": "Bad named entity: boxV without a semi-colon",
- "output": [
- [
- "Character",
- "&boxV"
- ]
- ]
- },
- {
- "input": "║",
- "description": "Named entity: boxV; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2551"
- ]
- ]
- },
- {
- "input": "&boxVH",
- "description": "Bad named entity: boxVH without a semi-colon",
- "output": [
- [
- "Character",
- "&boxVH"
- ]
- ]
- },
- {
- "input": "╬",
- "description": "Named entity: boxVH; with a semi-colon",
- "output": [
- [
- "Character",
- "\u256c"
- ]
- ]
- },
- {
- "input": "&boxVL",
- "description": "Bad named entity: boxVL without a semi-colon",
- "output": [
- [
- "Character",
- "&boxVL"
- ]
- ]
- },
- {
- "input": "╣",
- "description": "Named entity: boxVL; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2563"
- ]
- ]
- },
- {
- "input": "&boxVR",
- "description": "Bad named entity: boxVR without a semi-colon",
- "output": [
- [
- "Character",
- "&boxVR"
- ]
- ]
- },
- {
- "input": "╠",
- "description": "Named entity: boxVR; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2560"
- ]
- ]
- },
- {
- "input": "&boxVh",
- "description": "Bad named entity: boxVh without a semi-colon",
- "output": [
- [
- "Character",
- "&boxVh"
- ]
- ]
- },
- {
- "input": "╫",
- "description": "Named entity: boxVh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u256b"
- ]
- ]
- },
- {
- "input": "&boxVl",
- "description": "Bad named entity: boxVl without a semi-colon",
- "output": [
- [
- "Character",
- "&boxVl"
- ]
- ]
- },
- {
- "input": "╢",
- "description": "Named entity: boxVl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2562"
- ]
- ]
- },
- {
- "input": "&boxVr",
- "description": "Bad named entity: boxVr without a semi-colon",
- "output": [
- [
- "Character",
- "&boxVr"
- ]
- ]
- },
- {
- "input": "╟",
- "description": "Named entity: boxVr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u255f"
- ]
- ]
- },
- {
- "input": "&boxbox",
- "description": "Bad named entity: boxbox without a semi-colon",
- "output": [
- [
- "Character",
- "&boxbox"
- ]
- ]
- },
- {
- "input": "⧉",
- "description": "Named entity: boxbox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29c9"
- ]
- ]
- },
- {
- "input": "&boxdL",
- "description": "Bad named entity: boxdL without a semi-colon",
- "output": [
- [
- "Character",
- "&boxdL"
- ]
- ]
- },
- {
- "input": "╕",
- "description": "Named entity: boxdL; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2555"
- ]
- ]
- },
- {
- "input": "&boxdR",
- "description": "Bad named entity: boxdR without a semi-colon",
- "output": [
- [
- "Character",
- "&boxdR"
- ]
- ]
- },
- {
- "input": "╒",
- "description": "Named entity: boxdR; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2552"
- ]
- ]
- },
- {
- "input": "&boxdl",
- "description": "Bad named entity: boxdl without a semi-colon",
- "output": [
- [
- "Character",
- "&boxdl"
- ]
- ]
- },
- {
- "input": "┐",
- "description": "Named entity: boxdl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2510"
- ]
- ]
- },
- {
- "input": "&boxdr",
- "description": "Bad named entity: boxdr without a semi-colon",
- "output": [
- [
- "Character",
- "&boxdr"
- ]
- ]
- },
- {
- "input": "┌",
- "description": "Named entity: boxdr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u250c"
- ]
- ]
- },
- {
- "input": "&boxh",
- "description": "Bad named entity: boxh without a semi-colon",
- "output": [
- [
- "Character",
- "&boxh"
- ]
- ]
- },
- {
- "input": "─",
- "description": "Named entity: boxh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2500"
- ]
- ]
- },
- {
- "input": "&boxhD",
- "description": "Bad named entity: boxhD without a semi-colon",
- "output": [
- [
- "Character",
- "&boxhD"
- ]
- ]
- },
- {
- "input": "╥",
- "description": "Named entity: boxhD; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2565"
- ]
- ]
- },
- {
- "input": "&boxhU",
- "description": "Bad named entity: boxhU without a semi-colon",
- "output": [
- [
- "Character",
- "&boxhU"
- ]
- ]
- },
- {
- "input": "╨",
- "description": "Named entity: boxhU; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2568"
- ]
- ]
- },
- {
- "input": "&boxhd",
- "description": "Bad named entity: boxhd without a semi-colon",
- "output": [
- [
- "Character",
- "&boxhd"
- ]
- ]
- },
- {
- "input": "┬",
- "description": "Named entity: boxhd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u252c"
- ]
- ]
- },
- {
- "input": "&boxhu",
- "description": "Bad named entity: boxhu without a semi-colon",
- "output": [
- [
- "Character",
- "&boxhu"
- ]
- ]
- },
- {
- "input": "┴",
- "description": "Named entity: boxhu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2534"
- ]
- ]
- },
- {
- "input": "&boxminus",
- "description": "Bad named entity: boxminus without a semi-colon",
- "output": [
- [
- "Character",
- "&boxminus"
- ]
- ]
- },
- {
- "input": "⊟",
- "description": "Named entity: boxminus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229f"
- ]
- ]
- },
- {
- "input": "&boxplus",
- "description": "Bad named entity: boxplus without a semi-colon",
- "output": [
- [
- "Character",
- "&boxplus"
- ]
- ]
- },
- {
- "input": "⊞",
- "description": "Named entity: boxplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229e"
- ]
- ]
- },
- {
- "input": "&boxtimes",
- "description": "Bad named entity: boxtimes without a semi-colon",
- "output": [
- [
- "Character",
- "&boxtimes"
- ]
- ]
- },
- {
- "input": "⊠",
- "description": "Named entity: boxtimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a0"
- ]
- ]
- },
- {
- "input": "&boxuL",
- "description": "Bad named entity: boxuL without a semi-colon",
- "output": [
- [
- "Character",
- "&boxuL"
- ]
- ]
- },
- {
- "input": "╛",
- "description": "Named entity: boxuL; with a semi-colon",
- "output": [
- [
- "Character",
- "\u255b"
- ]
- ]
- },
- {
- "input": "&boxuR",
- "description": "Bad named entity: boxuR without a semi-colon",
- "output": [
- [
- "Character",
- "&boxuR"
- ]
- ]
- },
- {
- "input": "╘",
- "description": "Named entity: boxuR; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2558"
- ]
- ]
- },
- {
- "input": "&boxul",
- "description": "Bad named entity: boxul without a semi-colon",
- "output": [
- [
- "Character",
- "&boxul"
- ]
- ]
- },
- {
- "input": "┘",
- "description": "Named entity: boxul; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2518"
- ]
- ]
- },
- {
- "input": "&boxur",
- "description": "Bad named entity: boxur without a semi-colon",
- "output": [
- [
- "Character",
- "&boxur"
- ]
- ]
- },
- {
- "input": "└",
- "description": "Named entity: boxur; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2514"
- ]
- ]
- },
- {
- "input": "&boxv",
- "description": "Bad named entity: boxv without a semi-colon",
- "output": [
- [
- "Character",
- "&boxv"
- ]
- ]
- },
- {
- "input": "│",
- "description": "Named entity: boxv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2502"
- ]
- ]
- },
- {
- "input": "&boxvH",
- "description": "Bad named entity: boxvH without a semi-colon",
- "output": [
- [
- "Character",
- "&boxvH"
- ]
- ]
- },
- {
- "input": "╪",
- "description": "Named entity: boxvH; with a semi-colon",
- "output": [
- [
- "Character",
- "\u256a"
- ]
- ]
- },
- {
- "input": "&boxvL",
- "description": "Bad named entity: boxvL without a semi-colon",
- "output": [
- [
- "Character",
- "&boxvL"
- ]
- ]
- },
- {
- "input": "╡",
- "description": "Named entity: boxvL; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2561"
- ]
- ]
- },
- {
- "input": "&boxvR",
- "description": "Bad named entity: boxvR without a semi-colon",
- "output": [
- [
- "Character",
- "&boxvR"
- ]
- ]
- },
- {
- "input": "╞",
- "description": "Named entity: boxvR; with a semi-colon",
- "output": [
- [
- "Character",
- "\u255e"
- ]
- ]
- },
- {
- "input": "&boxvh",
- "description": "Bad named entity: boxvh without a semi-colon",
- "output": [
- [
- "Character",
- "&boxvh"
- ]
- ]
- },
- {
- "input": "┼",
- "description": "Named entity: boxvh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u253c"
- ]
- ]
- },
- {
- "input": "&boxvl",
- "description": "Bad named entity: boxvl without a semi-colon",
- "output": [
- [
- "Character",
- "&boxvl"
- ]
- ]
- },
- {
- "input": "┤",
- "description": "Named entity: boxvl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2524"
- ]
- ]
- },
- {
- "input": "&boxvr",
- "description": "Bad named entity: boxvr without a semi-colon",
- "output": [
- [
- "Character",
- "&boxvr"
- ]
- ]
- },
- {
- "input": "├",
- "description": "Named entity: boxvr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u251c"
- ]
- ]
- },
- {
- "input": "&bprime",
- "description": "Bad named entity: bprime without a semi-colon",
- "output": [
- [
- "Character",
- "&bprime"
- ]
- ]
- },
- {
- "input": "‵",
- "description": "Named entity: bprime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2035"
- ]
- ]
- },
- {
- "input": "&breve",
- "description": "Bad named entity: breve without a semi-colon",
- "output": [
- [
- "Character",
- "&breve"
- ]
- ]
- },
- {
- "input": "˘",
- "description": "Named entity: breve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02d8"
- ]
- ]
- },
- {
- "input": "¦",
- "description": "Named entity: brvbar without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a6"
- ]
- ]
- },
- {
- "input": "¦",
- "description": "Named entity: brvbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a6"
- ]
- ]
- },
- {
- "input": "&bscr",
- "description": "Bad named entity: bscr without a semi-colon",
- "output": [
- [
- "Character",
- "&bscr"
- ]
- ]
- },
- {
- "input": "𝒷",
- "description": "Named entity: bscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb7"
- ]
- ]
- },
- {
- "input": "&bsemi",
- "description": "Bad named entity: bsemi without a semi-colon",
- "output": [
- [
- "Character",
- "&bsemi"
- ]
- ]
- },
- {
- "input": "⁏",
- "description": "Named entity: bsemi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u204f"
- ]
- ]
- },
- {
- "input": "&bsim",
- "description": "Bad named entity: bsim without a semi-colon",
- "output": [
- [
- "Character",
- "&bsim"
- ]
- ]
- },
- {
- "input": "∽",
- "description": "Named entity: bsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223d"
- ]
- ]
- },
- {
- "input": "&bsime",
- "description": "Bad named entity: bsime without a semi-colon",
- "output": [
- [
- "Character",
- "&bsime"
- ]
- ]
- },
- {
- "input": "⋍",
- "description": "Named entity: bsime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22cd"
- ]
- ]
- },
- {
- "input": "&bsol",
- "description": "Bad named entity: bsol without a semi-colon",
- "output": [
- [
- "Character",
- "&bsol"
- ]
- ]
- },
- {
- "input": "\",
- "description": "Named entity: bsol; with a semi-colon",
- "output": [
- [
- "Character",
- "\\"
- ]
- ]
- },
- {
- "input": "&bsolb",
- "description": "Bad named entity: bsolb without a semi-colon",
- "output": [
- [
- "Character",
- "&bsolb"
- ]
- ]
- },
- {
- "input": "⧅",
- "description": "Named entity: bsolb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29c5"
- ]
- ]
- },
- {
- "input": "&bsolhsub",
- "description": "Bad named entity: bsolhsub without a semi-colon",
- "output": [
- [
- "Character",
- "&bsolhsub"
- ]
- ]
- },
- {
- "input": "⟈",
- "description": "Named entity: bsolhsub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27c8"
- ]
- ]
- },
- {
- "input": "&bull",
- "description": "Bad named entity: bull without a semi-colon",
- "output": [
- [
- "Character",
- "&bull"
- ]
- ]
- },
- {
- "input": "•",
- "description": "Named entity: bull; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2022"
- ]
- ]
- },
- {
- "input": "&bullet",
- "description": "Bad named entity: bullet without a semi-colon",
- "output": [
- [
- "Character",
- "&bullet"
- ]
- ]
- },
- {
- "input": "•",
- "description": "Named entity: bullet; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2022"
- ]
- ]
- },
- {
- "input": "&bump",
- "description": "Bad named entity: bump without a semi-colon",
- "output": [
- [
- "Character",
- "&bump"
- ]
- ]
- },
- {
- "input": "≎",
- "description": "Named entity: bump; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224e"
- ]
- ]
- },
- {
- "input": "&bumpE",
- "description": "Bad named entity: bumpE without a semi-colon",
- "output": [
- [
- "Character",
- "&bumpE"
- ]
- ]
- },
- {
- "input": "⪮",
- "description": "Named entity: bumpE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aae"
- ]
- ]
- },
- {
- "input": "&bumpe",
- "description": "Bad named entity: bumpe without a semi-colon",
- "output": [
- [
- "Character",
- "&bumpe"
- ]
- ]
- },
- {
- "input": "≏",
- "description": "Named entity: bumpe; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224f"
- ]
- ]
- },
- {
- "input": "&bumpeq",
- "description": "Bad named entity: bumpeq without a semi-colon",
- "output": [
- [
- "Character",
- "&bumpeq"
- ]
- ]
- },
- {
- "input": "≏",
- "description": "Named entity: bumpeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224f"
- ]
- ]
- },
- {
- "input": "&cacute",
- "description": "Bad named entity: cacute without a semi-colon",
- "output": [
- [
- "Character",
- "&cacute"
- ]
- ]
- },
- {
- "input": "ć",
- "description": "Named entity: cacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0107"
- ]
- ]
- },
- {
- "input": "&cap",
- "description": "Bad named entity: cap without a semi-colon",
- "output": [
- [
- "Character",
- "&cap"
- ]
- ]
- },
- {
- "input": "∩",
- "description": "Named entity: cap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2229"
- ]
- ]
- },
- {
- "input": "&capand",
- "description": "Bad named entity: capand without a semi-colon",
- "output": [
- [
- "Character",
- "&capand"
- ]
- ]
- },
- {
- "input": "⩄",
- "description": "Named entity: capand; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a44"
- ]
- ]
- },
- {
- "input": "&capbrcup",
- "description": "Bad named entity: capbrcup without a semi-colon",
- "output": [
- [
- "Character",
- "&capbrcup"
- ]
- ]
- },
- {
- "input": "⩉",
- "description": "Named entity: capbrcup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a49"
- ]
- ]
- },
- {
- "input": "&capcap",
- "description": "Bad named entity: capcap without a semi-colon",
- "output": [
- [
- "Character",
- "&capcap"
- ]
- ]
- },
- {
- "input": "⩋",
- "description": "Named entity: capcap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a4b"
- ]
- ]
- },
- {
- "input": "&capcup",
- "description": "Bad named entity: capcup without a semi-colon",
- "output": [
- [
- "Character",
- "&capcup"
- ]
- ]
- },
- {
- "input": "⩇",
- "description": "Named entity: capcup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a47"
- ]
- ]
- },
- {
- "input": "&capdot",
- "description": "Bad named entity: capdot without a semi-colon",
- "output": [
- [
- "Character",
- "&capdot"
- ]
- ]
- },
- {
- "input": "⩀",
- "description": "Named entity: capdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a40"
- ]
- ]
- },
- {
- "input": "&caps",
- "description": "Bad named entity: caps without a semi-colon",
- "output": [
- [
- "Character",
- "&caps"
- ]
- ]
- },
- {
- "input": "∩︀",
- "description": "Named entity: caps; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2229\ufe00"
- ]
- ]
- },
- {
- "input": "&caret",
- "description": "Bad named entity: caret without a semi-colon",
- "output": [
- [
- "Character",
- "&caret"
- ]
- ]
- },
- {
- "input": "⁁",
- "description": "Named entity: caret; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2041"
- ]
- ]
- },
- {
- "input": "&caron",
- "description": "Bad named entity: caron without a semi-colon",
- "output": [
- [
- "Character",
- "&caron"
- ]
- ]
- },
- {
- "input": "ˇ",
- "description": "Named entity: caron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02c7"
- ]
- ]
- },
- {
- "input": "&ccaps",
- "description": "Bad named entity: ccaps without a semi-colon",
- "output": [
- [
- "Character",
- "&ccaps"
- ]
- ]
- },
- {
- "input": "⩍",
- "description": "Named entity: ccaps; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a4d"
- ]
- ]
- },
- {
- "input": "&ccaron",
- "description": "Bad named entity: ccaron without a semi-colon",
- "output": [
- [
- "Character",
- "&ccaron"
- ]
- ]
- },
- {
- "input": "č",
- "description": "Named entity: ccaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u010d"
- ]
- ]
- },
- {
- "input": "ç",
- "description": "Named entity: ccedil without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e7"
- ]
- ]
- },
- {
- "input": "ç",
- "description": "Named entity: ccedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e7"
- ]
- ]
- },
- {
- "input": "&ccirc",
- "description": "Bad named entity: ccirc without a semi-colon",
- "output": [
- [
- "Character",
- "&ccirc"
- ]
- ]
- },
- {
- "input": "ĉ",
- "description": "Named entity: ccirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0109"
- ]
- ]
- },
- {
- "input": "&ccups",
- "description": "Bad named entity: ccups without a semi-colon",
- "output": [
- [
- "Character",
- "&ccups"
- ]
- ]
- },
- {
- "input": "⩌",
- "description": "Named entity: ccups; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a4c"
- ]
- ]
- },
- {
- "input": "&ccupssm",
- "description": "Bad named entity: ccupssm without a semi-colon",
- "output": [
- [
- "Character",
- "&ccupssm"
- ]
- ]
- },
- {
- "input": "⩐",
- "description": "Named entity: ccupssm; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a50"
- ]
- ]
- },
- {
- "input": "&cdot",
- "description": "Bad named entity: cdot without a semi-colon",
- "output": [
- [
- "Character",
- "&cdot"
- ]
- ]
- },
- {
- "input": "ċ",
- "description": "Named entity: cdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u010b"
- ]
- ]
- },
- {
- "input": "¸",
- "description": "Named entity: cedil without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b8"
- ]
- ]
- },
- {
- "input": "¸",
- "description": "Named entity: cedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b8"
- ]
- ]
- },
- {
- "input": "&cemptyv",
- "description": "Bad named entity: cemptyv without a semi-colon",
- "output": [
- [
- "Character",
- "&cemptyv"
- ]
- ]
- },
- {
- "input": "⦲",
- "description": "Named entity: cemptyv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b2"
- ]
- ]
- },
- {
- "input": "¢",
- "description": "Named entity: cent without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a2"
- ]
- ]
- },
- {
- "input": "¢",
- "description": "Named entity: cent; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a2"
- ]
- ]
- },
- {
- "input": "·",
- "description": "Named entity: centerdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b7"
- ]
- ]
- },
- {
- "input": "&cfr",
- "description": "Bad named entity: cfr without a semi-colon",
- "output": [
- [
- "Character",
- "&cfr"
- ]
- ]
- },
- {
- "input": "𝔠",
- "description": "Named entity: cfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd20"
- ]
- ]
- },
- {
- "input": "&chcy",
- "description": "Bad named entity: chcy without a semi-colon",
- "output": [
- [
- "Character",
- "&chcy"
- ]
- ]
- },
- {
- "input": "ч",
- "description": "Named entity: chcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0447"
- ]
- ]
- },
- {
- "input": "&check",
- "description": "Bad named entity: check without a semi-colon",
- "output": [
- [
- "Character",
- "&check"
- ]
- ]
- },
- {
- "input": "✓",
- "description": "Named entity: check; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2713"
- ]
- ]
- },
- {
- "input": "&checkmark",
- "description": "Bad named entity: checkmark without a semi-colon",
- "output": [
- [
- "Character",
- "&checkmark"
- ]
- ]
- },
- {
- "input": "✓",
- "description": "Named entity: checkmark; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2713"
- ]
- ]
- },
- {
- "input": "&chi",
- "description": "Bad named entity: chi without a semi-colon",
- "output": [
- [
- "Character",
- "&chi"
- ]
- ]
- },
- {
- "input": "χ",
- "description": "Named entity: chi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c7"
- ]
- ]
- },
- {
- "input": "&cir",
- "description": "Bad named entity: cir without a semi-colon",
- "output": [
- [
- "Character",
- "&cir"
- ]
- ]
- },
- {
- "input": "○",
- "description": "Named entity: cir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25cb"
- ]
- ]
- },
- {
- "input": "&cirE",
- "description": "Bad named entity: cirE without a semi-colon",
- "output": [
- [
- "Character",
- "&cirE"
- ]
- ]
- },
- {
- "input": "⧃",
- "description": "Named entity: cirE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29c3"
- ]
- ]
- },
- {
- "input": "&circ",
- "description": "Bad named entity: circ without a semi-colon",
- "output": [
- [
- "Character",
- "&circ"
- ]
- ]
- },
- {
- "input": "ˆ",
- "description": "Named entity: circ; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02c6"
- ]
- ]
- },
- {
- "input": "&circeq",
- "description": "Bad named entity: circeq without a semi-colon",
- "output": [
- [
- "Character",
- "&circeq"
- ]
- ]
- },
- {
- "input": "≗",
- "description": "Named entity: circeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2257"
- ]
- ]
- },
- {
- "input": "&circlearrowleft",
- "description": "Bad named entity: circlearrowleft without a semi-colon",
- "output": [
- [
- "Character",
- "&circlearrowleft"
- ]
- ]
- },
- {
- "input": "↺",
- "description": "Named entity: circlearrowleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ba"
- ]
- ]
- },
- {
- "input": "&circlearrowright",
- "description": "Bad named entity: circlearrowright without a semi-colon",
- "output": [
- [
- "Character",
- "&circlearrowright"
- ]
- ]
- },
- {
- "input": "↻",
- "description": "Named entity: circlearrowright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bb"
- ]
- ]
- },
- {
- "input": "&circledR",
- "description": "Bad named entity: circledR without a semi-colon",
- "output": [
- [
- "Character",
- "&circledR"
- ]
- ]
- },
- {
- "input": "®",
- "description": "Named entity: circledR; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ae"
- ]
- ]
- },
- {
- "input": "&circledS",
- "description": "Bad named entity: circledS without a semi-colon",
- "output": [
- [
- "Character",
- "&circledS"
- ]
- ]
- },
- {
- "input": "Ⓢ",
- "description": "Named entity: circledS; with a semi-colon",
- "output": [
- [
- "Character",
- "\u24c8"
- ]
- ]
- },
- {
- "input": "&circledast",
- "description": "Bad named entity: circledast without a semi-colon",
- "output": [
- [
- "Character",
- "&circledast"
- ]
- ]
- },
- {
- "input": "⊛",
- "description": "Named entity: circledast; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229b"
- ]
- ]
- },
- {
- "input": "&circledcirc",
- "description": "Bad named entity: circledcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&circledcirc"
- ]
- ]
- },
- {
- "input": "⊚",
- "description": "Named entity: circledcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229a"
- ]
- ]
- },
- {
- "input": "&circleddash",
- "description": "Bad named entity: circleddash without a semi-colon",
- "output": [
- [
- "Character",
- "&circleddash"
- ]
- ]
- },
- {
- "input": "⊝",
- "description": "Named entity: circleddash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229d"
- ]
- ]
- },
- {
- "input": "&cire",
- "description": "Bad named entity: cire without a semi-colon",
- "output": [
- [
- "Character",
- "&cire"
- ]
- ]
- },
- {
- "input": "≗",
- "description": "Named entity: cire; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2257"
- ]
- ]
- },
- {
- "input": "&cirfnint",
- "description": "Bad named entity: cirfnint without a semi-colon",
- "output": [
- [
- "Character",
- "&cirfnint"
- ]
- ]
- },
- {
- "input": "⨐",
- "description": "Named entity: cirfnint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a10"
- ]
- ]
- },
- {
- "input": "&cirmid",
- "description": "Bad named entity: cirmid without a semi-colon",
- "output": [
- [
- "Character",
- "&cirmid"
- ]
- ]
- },
- {
- "input": "⫯",
- "description": "Named entity: cirmid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aef"
- ]
- ]
- },
- {
- "input": "&cirscir",
- "description": "Bad named entity: cirscir without a semi-colon",
- "output": [
- [
- "Character",
- "&cirscir"
- ]
- ]
- },
- {
- "input": "⧂",
- "description": "Named entity: cirscir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29c2"
- ]
- ]
- },
- {
- "input": "&clubs",
- "description": "Bad named entity: clubs without a semi-colon",
- "output": [
- [
- "Character",
- "&clubs"
- ]
- ]
- },
- {
- "input": "♣",
- "description": "Named entity: clubs; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2663"
- ]
- ]
- },
- {
- "input": "&clubsuit",
- "description": "Bad named entity: clubsuit without a semi-colon",
- "output": [
- [
- "Character",
- "&clubsuit"
- ]
- ]
- },
- {
- "input": "♣",
- "description": "Named entity: clubsuit; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2663"
- ]
- ]
- },
- {
- "input": "&colon",
- "description": "Bad named entity: colon without a semi-colon",
- "output": [
- [
- "Character",
- "&colon"
- ]
- ]
- },
- {
- "input": ":",
- "description": "Named entity: colon; with a semi-colon",
- "output": [
- [
- "Character",
- ":"
- ]
- ]
- },
- {
- "input": "&colone",
- "description": "Bad named entity: colone without a semi-colon",
- "output": [
- [
- "Character",
- "&colone"
- ]
- ]
- },
- {
- "input": "≔",
- "description": "Named entity: colone; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2254"
- ]
- ]
- },
- {
- "input": "&coloneq",
- "description": "Bad named entity: coloneq without a semi-colon",
- "output": [
- [
- "Character",
- "&coloneq"
- ]
- ]
- },
- {
- "input": "≔",
- "description": "Named entity: coloneq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2254"
- ]
- ]
- },
- {
- "input": "&comma",
- "description": "Bad named entity: comma without a semi-colon",
- "output": [
- [
- "Character",
- "&comma"
- ]
- ]
- },
- {
- "input": ",",
- "description": "Named entity: comma; with a semi-colon",
- "output": [
- [
- "Character",
- ","
- ]
- ]
- },
- {
- "input": "&commat",
- "description": "Bad named entity: commat without a semi-colon",
- "output": [
- [
- "Character",
- "&commat"
- ]
- ]
- },
- {
- "input": "@",
- "description": "Named entity: commat; with a semi-colon",
- "output": [
- [
- "Character",
- "@"
- ]
- ]
- },
- {
- "input": "&comp",
- "description": "Bad named entity: comp without a semi-colon",
- "output": [
- [
- "Character",
- "&comp"
- ]
- ]
- },
- {
- "input": "∁",
- "description": "Named entity: comp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2201"
- ]
- ]
- },
- {
- "input": "&compfn",
- "description": "Bad named entity: compfn without a semi-colon",
- "output": [
- [
- "Character",
- "&compfn"
- ]
- ]
- },
- {
- "input": "∘",
- "description": "Named entity: compfn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2218"
- ]
- ]
- },
- {
- "input": "&complement",
- "description": "Bad named entity: complement without a semi-colon",
- "output": [
- [
- "Character",
- "&complement"
- ]
- ]
- },
- {
- "input": "∁",
- "description": "Named entity: complement; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2201"
- ]
- ]
- },
- {
- "input": "&complexes",
- "description": "Bad named entity: complexes without a semi-colon",
- "output": [
- [
- "Character",
- "&complexes"
- ]
- ]
- },
- {
- "input": "ℂ",
- "description": "Named entity: complexes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2102"
- ]
- ]
- },
- {
- "input": "&cong",
- "description": "Bad named entity: cong without a semi-colon",
- "output": [
- [
- "Character",
- "&cong"
- ]
- ]
- },
- {
- "input": "≅",
- "description": "Named entity: cong; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2245"
- ]
- ]
- },
- {
- "input": "&congdot",
- "description": "Bad named entity: congdot without a semi-colon",
- "output": [
- [
- "Character",
- "&congdot"
- ]
- ]
- },
- {
- "input": "⩭",
- "description": "Named entity: congdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a6d"
- ]
- ]
- },
- {
- "input": "&conint",
- "description": "Bad named entity: conint without a semi-colon",
- "output": [
- [
- "Character",
- "&conint"
- ]
- ]
- },
- {
- "input": "∮",
- "description": "Named entity: conint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222e"
- ]
- ]
- },
- {
- "input": "&copf",
- "description": "Bad named entity: copf without a semi-colon",
- "output": [
- [
- "Character",
- "&copf"
- ]
- ]
- },
- {
- "input": "𝕔",
- "description": "Named entity: copf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd54"
- ]
- ]
- },
- {
- "input": "&coprod",
- "description": "Bad named entity: coprod without a semi-colon",
- "output": [
- [
- "Character",
- "&coprod"
- ]
- ]
- },
- {
- "input": "∐",
- "description": "Named entity: coprod; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2210"
- ]
- ]
- },
- {
- "input": "©",
- "description": "Named entity: copy without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a9"
- ]
- ]
- },
- {
- "input": "©",
- "description": "Named entity: copy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a9"
- ]
- ]
- },
- {
- "input": "℗",
- "description": "Named entity: copysr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2117"
- ]
- ]
- },
- {
- "input": "&crarr",
- "description": "Bad named entity: crarr without a semi-colon",
- "output": [
- [
- "Character",
- "&crarr"
- ]
- ]
- },
- {
- "input": "↵",
- "description": "Named entity: crarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b5"
- ]
- ]
- },
- {
- "input": "&cross",
- "description": "Bad named entity: cross without a semi-colon",
- "output": [
- [
- "Character",
- "&cross"
- ]
- ]
- },
- {
- "input": "✗",
- "description": "Named entity: cross; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2717"
- ]
- ]
- },
- {
- "input": "&cscr",
- "description": "Bad named entity: cscr without a semi-colon",
- "output": [
- [
- "Character",
- "&cscr"
- ]
- ]
- },
- {
- "input": "𝒸",
- "description": "Named entity: cscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb8"
- ]
- ]
- },
- {
- "input": "&csub",
- "description": "Bad named entity: csub without a semi-colon",
- "output": [
- [
- "Character",
- "&csub"
- ]
- ]
- },
- {
- "input": "⫏",
- "description": "Named entity: csub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acf"
- ]
- ]
- },
- {
- "input": "&csube",
- "description": "Bad named entity: csube without a semi-colon",
- "output": [
- [
- "Character",
- "&csube"
- ]
- ]
- },
- {
- "input": "⫑",
- "description": "Named entity: csube; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad1"
- ]
- ]
- },
- {
- "input": "&csup",
- "description": "Bad named entity: csup without a semi-colon",
- "output": [
- [
- "Character",
- "&csup"
- ]
- ]
- },
- {
- "input": "⫐",
- "description": "Named entity: csup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad0"
- ]
- ]
- },
- {
- "input": "&csupe",
- "description": "Bad named entity: csupe without a semi-colon",
- "output": [
- [
- "Character",
- "&csupe"
- ]
- ]
- },
- {
- "input": "⫒",
- "description": "Named entity: csupe; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad2"
- ]
- ]
- },
- {
- "input": "&ctdot",
- "description": "Bad named entity: ctdot without a semi-colon",
- "output": [
- [
- "Character",
- "&ctdot"
- ]
- ]
- },
- {
- "input": "⋯",
- "description": "Named entity: ctdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ef"
- ]
- ]
- },
- {
- "input": "&cudarrl",
- "description": "Bad named entity: cudarrl without a semi-colon",
- "output": [
- [
- "Character",
- "&cudarrl"
- ]
- ]
- },
- {
- "input": "⤸",
- "description": "Named entity: cudarrl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2938"
- ]
- ]
- },
- {
- "input": "&cudarrr",
- "description": "Bad named entity: cudarrr without a semi-colon",
- "output": [
- [
- "Character",
- "&cudarrr"
- ]
- ]
- },
- {
- "input": "⤵",
- "description": "Named entity: cudarrr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2935"
- ]
- ]
- },
- {
- "input": "&cuepr",
- "description": "Bad named entity: cuepr without a semi-colon",
- "output": [
- [
- "Character",
- "&cuepr"
- ]
- ]
- },
- {
- "input": "⋞",
- "description": "Named entity: cuepr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22de"
- ]
- ]
- },
- {
- "input": "&cuesc",
- "description": "Bad named entity: cuesc without a semi-colon",
- "output": [
- [
- "Character",
- "&cuesc"
- ]
- ]
- },
- {
- "input": "⋟",
- "description": "Named entity: cuesc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22df"
- ]
- ]
- },
- {
- "input": "&cularr",
- "description": "Bad named entity: cularr without a semi-colon",
- "output": [
- [
- "Character",
- "&cularr"
- ]
- ]
- },
- {
- "input": "↶",
- "description": "Named entity: cularr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b6"
- ]
- ]
- },
- {
- "input": "&cularrp",
- "description": "Bad named entity: cularrp without a semi-colon",
- "output": [
- [
- "Character",
- "&cularrp"
- ]
- ]
- },
- {
- "input": "⤽",
- "description": "Named entity: cularrp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u293d"
- ]
- ]
- },
- {
- "input": "&cup",
- "description": "Bad named entity: cup without a semi-colon",
- "output": [
- [
- "Character",
- "&cup"
- ]
- ]
- },
- {
- "input": "∪",
- "description": "Named entity: cup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222a"
- ]
- ]
- },
- {
- "input": "&cupbrcap",
- "description": "Bad named entity: cupbrcap without a semi-colon",
- "output": [
- [
- "Character",
- "&cupbrcap"
- ]
- ]
- },
- {
- "input": "⩈",
- "description": "Named entity: cupbrcap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a48"
- ]
- ]
- },
- {
- "input": "&cupcap",
- "description": "Bad named entity: cupcap without a semi-colon",
- "output": [
- [
- "Character",
- "&cupcap"
- ]
- ]
- },
- {
- "input": "⩆",
- "description": "Named entity: cupcap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a46"
- ]
- ]
- },
- {
- "input": "&cupcup",
- "description": "Bad named entity: cupcup without a semi-colon",
- "output": [
- [
- "Character",
- "&cupcup"
- ]
- ]
- },
- {
- "input": "⩊",
- "description": "Named entity: cupcup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a4a"
- ]
- ]
- },
- {
- "input": "&cupdot",
- "description": "Bad named entity: cupdot without a semi-colon",
- "output": [
- [
- "Character",
- "&cupdot"
- ]
- ]
- },
- {
- "input": "⊍",
- "description": "Named entity: cupdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228d"
- ]
- ]
- },
- {
- "input": "&cupor",
- "description": "Bad named entity: cupor without a semi-colon",
- "output": [
- [
- "Character",
- "&cupor"
- ]
- ]
- },
- {
- "input": "⩅",
- "description": "Named entity: cupor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a45"
- ]
- ]
- },
- {
- "input": "&cups",
- "description": "Bad named entity: cups without a semi-colon",
- "output": [
- [
- "Character",
- "&cups"
- ]
- ]
- },
- {
- "input": "∪︀",
- "description": "Named entity: cups; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222a\ufe00"
- ]
- ]
- },
- {
- "input": "&curarr",
- "description": "Bad named entity: curarr without a semi-colon",
- "output": [
- [
- "Character",
- "&curarr"
- ]
- ]
- },
- {
- "input": "↷",
- "description": "Named entity: curarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b7"
- ]
- ]
- },
- {
- "input": "&curarrm",
- "description": "Bad named entity: curarrm without a semi-colon",
- "output": [
- [
- "Character",
- "&curarrm"
- ]
- ]
- },
- {
- "input": "⤼",
- "description": "Named entity: curarrm; with a semi-colon",
- "output": [
- [
- "Character",
- "\u293c"
- ]
- ]
- },
- {
- "input": "&curlyeqprec",
- "description": "Bad named entity: curlyeqprec without a semi-colon",
- "output": [
- [
- "Character",
- "&curlyeqprec"
- ]
- ]
- },
- {
- "input": "⋞",
- "description": "Named entity: curlyeqprec; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22de"
- ]
- ]
- },
- {
- "input": "&curlyeqsucc",
- "description": "Bad named entity: curlyeqsucc without a semi-colon",
- "output": [
- [
- "Character",
- "&curlyeqsucc"
- ]
- ]
- },
- {
- "input": "⋟",
- "description": "Named entity: curlyeqsucc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22df"
- ]
- ]
- },
- {
- "input": "&curlyvee",
- "description": "Bad named entity: curlyvee without a semi-colon",
- "output": [
- [
- "Character",
- "&curlyvee"
- ]
- ]
- },
- {
- "input": "⋎",
- "description": "Named entity: curlyvee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ce"
- ]
- ]
- },
- {
- "input": "&curlywedge",
- "description": "Bad named entity: curlywedge without a semi-colon",
- "output": [
- [
- "Character",
- "&curlywedge"
- ]
- ]
- },
- {
- "input": "⋏",
- "description": "Named entity: curlywedge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22cf"
- ]
- ]
- },
- {
- "input": "¤",
- "description": "Named entity: curren without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a4"
- ]
- ]
- },
- {
- "input": "¤",
- "description": "Named entity: curren; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a4"
- ]
- ]
- },
- {
- "input": "&curvearrowleft",
- "description": "Bad named entity: curvearrowleft without a semi-colon",
- "output": [
- [
- "Character",
- "&curvearrowleft"
- ]
- ]
- },
- {
- "input": "↶",
- "description": "Named entity: curvearrowleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b6"
- ]
- ]
- },
- {
- "input": "&curvearrowright",
- "description": "Bad named entity: curvearrowright without a semi-colon",
- "output": [
- [
- "Character",
- "&curvearrowright"
- ]
- ]
- },
- {
- "input": "↷",
- "description": "Named entity: curvearrowright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b7"
- ]
- ]
- },
- {
- "input": "&cuvee",
- "description": "Bad named entity: cuvee without a semi-colon",
- "output": [
- [
- "Character",
- "&cuvee"
- ]
- ]
- },
- {
- "input": "⋎",
- "description": "Named entity: cuvee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ce"
- ]
- ]
- },
- {
- "input": "&cuwed",
- "description": "Bad named entity: cuwed without a semi-colon",
- "output": [
- [
- "Character",
- "&cuwed"
- ]
- ]
- },
- {
- "input": "⋏",
- "description": "Named entity: cuwed; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22cf"
- ]
- ]
- },
- {
- "input": "&cwconint",
- "description": "Bad named entity: cwconint without a semi-colon",
- "output": [
- [
- "Character",
- "&cwconint"
- ]
- ]
- },
- {
- "input": "∲",
- "description": "Named entity: cwconint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2232"
- ]
- ]
- },
- {
- "input": "&cwint",
- "description": "Bad named entity: cwint without a semi-colon",
- "output": [
- [
- "Character",
- "&cwint"
- ]
- ]
- },
- {
- "input": "∱",
- "description": "Named entity: cwint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2231"
- ]
- ]
- },
- {
- "input": "&cylcty",
- "description": "Bad named entity: cylcty without a semi-colon",
- "output": [
- [
- "Character",
- "&cylcty"
- ]
- ]
- },
- {
- "input": "⌭",
- "description": "Named entity: cylcty; with a semi-colon",
- "output": [
- [
- "Character",
- "\u232d"
- ]
- ]
- },
- {
- "input": "&dArr",
- "description": "Bad named entity: dArr without a semi-colon",
- "output": [
- [
- "Character",
- "&dArr"
- ]
- ]
- },
- {
- "input": "⇓",
- "description": "Named entity: dArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d3"
- ]
- ]
- },
- {
- "input": "&dHar",
- "description": "Bad named entity: dHar without a semi-colon",
- "output": [
- [
- "Character",
- "&dHar"
- ]
- ]
- },
- {
- "input": "⥥",
- "description": "Named entity: dHar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2965"
- ]
- ]
- },
- {
- "input": "&dagger",
- "description": "Bad named entity: dagger without a semi-colon",
- "output": [
- [
- "Character",
- "&dagger"
- ]
- ]
- },
- {
- "input": "†",
- "description": "Named entity: dagger; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2020"
- ]
- ]
- },
- {
- "input": "&daleth",
- "description": "Bad named entity: daleth without a semi-colon",
- "output": [
- [
- "Character",
- "&daleth"
- ]
- ]
- },
- {
- "input": "ℸ",
- "description": "Named entity: daleth; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2138"
- ]
- ]
- },
- {
- "input": "&darr",
- "description": "Bad named entity: darr without a semi-colon",
- "output": [
- [
- "Character",
- "&darr"
- ]
- ]
- },
- {
- "input": "↓",
- "description": "Named entity: darr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2193"
- ]
- ]
- },
- {
- "input": "&dash",
- "description": "Bad named entity: dash without a semi-colon",
- "output": [
- [
- "Character",
- "&dash"
- ]
- ]
- },
- {
- "input": "‐",
- "description": "Named entity: dash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2010"
- ]
- ]
- },
- {
- "input": "&dashv",
- "description": "Bad named entity: dashv without a semi-colon",
- "output": [
- [
- "Character",
- "&dashv"
- ]
- ]
- },
- {
- "input": "⊣",
- "description": "Named entity: dashv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a3"
- ]
- ]
- },
- {
- "input": "&dbkarow",
- "description": "Bad named entity: dbkarow without a semi-colon",
- "output": [
- [
- "Character",
- "&dbkarow"
- ]
- ]
- },
- {
- "input": "⤏",
- "description": "Named entity: dbkarow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u290f"
- ]
- ]
- },
- {
- "input": "&dblac",
- "description": "Bad named entity: dblac without a semi-colon",
- "output": [
- [
- "Character",
- "&dblac"
- ]
- ]
- },
- {
- "input": "˝",
- "description": "Named entity: dblac; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02dd"
- ]
- ]
- },
- {
- "input": "&dcaron",
- "description": "Bad named entity: dcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&dcaron"
- ]
- ]
- },
- {
- "input": "ď",
- "description": "Named entity: dcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u010f"
- ]
- ]
- },
- {
- "input": "&dcy",
- "description": "Bad named entity: dcy without a semi-colon",
- "output": [
- [
- "Character",
- "&dcy"
- ]
- ]
- },
- {
- "input": "д",
- "description": "Named entity: dcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0434"
- ]
- ]
- },
- {
- "input": "&dd",
- "description": "Bad named entity: dd without a semi-colon",
- "output": [
- [
- "Character",
- "&dd"
- ]
- ]
- },
- {
- "input": "ⅆ",
- "description": "Named entity: dd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2146"
- ]
- ]
- },
- {
- "input": "&ddagger",
- "description": "Bad named entity: ddagger without a semi-colon",
- "output": [
- [
- "Character",
- "&ddagger"
- ]
- ]
- },
- {
- "input": "‡",
- "description": "Named entity: ddagger; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2021"
- ]
- ]
- },
- {
- "input": "&ddarr",
- "description": "Bad named entity: ddarr without a semi-colon",
- "output": [
- [
- "Character",
- "&ddarr"
- ]
- ]
- },
- {
- "input": "⇊",
- "description": "Named entity: ddarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ca"
- ]
- ]
- },
- {
- "input": "&ddotseq",
- "description": "Bad named entity: ddotseq without a semi-colon",
- "output": [
- [
- "Character",
- "&ddotseq"
- ]
- ]
- },
- {
- "input": "⩷",
- "description": "Named entity: ddotseq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a77"
- ]
- ]
- },
- {
- "input": "°",
- "description": "Named entity: deg without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b0"
- ]
- ]
- },
- {
- "input": "°",
- "description": "Named entity: deg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b0"
- ]
- ]
- },
- {
- "input": "&delta",
- "description": "Bad named entity: delta without a semi-colon",
- "output": [
- [
- "Character",
- "&delta"
- ]
- ]
- },
- {
- "input": "δ",
- "description": "Named entity: delta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b4"
- ]
- ]
- },
- {
- "input": "&demptyv",
- "description": "Bad named entity: demptyv without a semi-colon",
- "output": [
- [
- "Character",
- "&demptyv"
- ]
- ]
- },
- {
- "input": "⦱",
- "description": "Named entity: demptyv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b1"
- ]
- ]
- },
- {
- "input": "&dfisht",
- "description": "Bad named entity: dfisht without a semi-colon",
- "output": [
- [
- "Character",
- "&dfisht"
- ]
- ]
- },
- {
- "input": "⥿",
- "description": "Named entity: dfisht; with a semi-colon",
- "output": [
- [
- "Character",
- "\u297f"
- ]
- ]
- },
- {
- "input": "&dfr",
- "description": "Bad named entity: dfr without a semi-colon",
- "output": [
- [
- "Character",
- "&dfr"
- ]
- ]
- },
- {
- "input": "𝔡",
- "description": "Named entity: dfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd21"
- ]
- ]
- },
- {
- "input": "&dharl",
- "description": "Bad named entity: dharl without a semi-colon",
- "output": [
- [
- "Character",
- "&dharl"
- ]
- ]
- },
- {
- "input": "⇃",
- "description": "Named entity: dharl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c3"
- ]
- ]
- },
- {
- "input": "&dharr",
- "description": "Bad named entity: dharr without a semi-colon",
- "output": [
- [
- "Character",
- "&dharr"
- ]
- ]
- },
- {
- "input": "⇂",
- "description": "Named entity: dharr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c2"
- ]
- ]
- },
- {
- "input": "&diam",
- "description": "Bad named entity: diam without a semi-colon",
- "output": [
- [
- "Character",
- "&diam"
- ]
- ]
- },
- {
- "input": "⋄",
- "description": "Named entity: diam; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c4"
- ]
- ]
- },
- {
- "input": "&diamond",
- "description": "Bad named entity: diamond without a semi-colon",
- "output": [
- [
- "Character",
- "&diamond"
- ]
- ]
- },
- {
- "input": "⋄",
- "description": "Named entity: diamond; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c4"
- ]
- ]
- },
- {
- "input": "&diamondsuit",
- "description": "Bad named entity: diamondsuit without a semi-colon",
- "output": [
- [
- "Character",
- "&diamondsuit"
- ]
- ]
- },
- {
- "input": "♦",
- "description": "Named entity: diamondsuit; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2666"
- ]
- ]
- },
- {
- "input": "&diams",
- "description": "Bad named entity: diams without a semi-colon",
- "output": [
- [
- "Character",
- "&diams"
- ]
- ]
- },
- {
- "input": "♦",
- "description": "Named entity: diams; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2666"
- ]
- ]
- },
- {
- "input": "&die",
- "description": "Bad named entity: die without a semi-colon",
- "output": [
- [
- "Character",
- "&die"
- ]
- ]
- },
- {
- "input": "¨",
- "description": "Named entity: die; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a8"
- ]
- ]
- },
- {
- "input": "&digamma",
- "description": "Bad named entity: digamma without a semi-colon",
- "output": [
- [
- "Character",
- "&digamma"
- ]
- ]
- },
- {
- "input": "ϝ",
- "description": "Named entity: digamma; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03dd"
- ]
- ]
- },
- {
- "input": "&disin",
- "description": "Bad named entity: disin without a semi-colon",
- "output": [
- [
- "Character",
- "&disin"
- ]
- ]
- },
- {
- "input": "⋲",
- "description": "Named entity: disin; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f2"
- ]
- ]
- },
- {
- "input": "&div",
- "description": "Bad named entity: div without a semi-colon",
- "output": [
- [
- "Character",
- "&div"
- ]
- ]
- },
- {
- "input": "÷",
- "description": "Named entity: div; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f7"
- ]
- ]
- },
- {
- "input": "÷",
- "description": "Named entity: divide without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f7"
- ]
- ]
- },
- {
- "input": "÷",
- "description": "Named entity: divide; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f7"
- ]
- ]
- },
- {
- "input": "⋇",
- "description": "Named entity: divideontimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c7"
- ]
- ]
- },
- {
- "input": "&divonx",
- "description": "Bad named entity: divonx without a semi-colon",
- "output": [
- [
- "Character",
- "&divonx"
- ]
- ]
- },
- {
- "input": "⋇",
- "description": "Named entity: divonx; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c7"
- ]
- ]
- },
- {
- "input": "&djcy",
- "description": "Bad named entity: djcy without a semi-colon",
- "output": [
- [
- "Character",
- "&djcy"
- ]
- ]
- },
- {
- "input": "ђ",
- "description": "Named entity: djcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0452"
- ]
- ]
- },
- {
- "input": "&dlcorn",
- "description": "Bad named entity: dlcorn without a semi-colon",
- "output": [
- [
- "Character",
- "&dlcorn"
- ]
- ]
- },
- {
- "input": "⌞",
- "description": "Named entity: dlcorn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u231e"
- ]
- ]
- },
- {
- "input": "&dlcrop",
- "description": "Bad named entity: dlcrop without a semi-colon",
- "output": [
- [
- "Character",
- "&dlcrop"
- ]
- ]
- },
- {
- "input": "⌍",
- "description": "Named entity: dlcrop; with a semi-colon",
- "output": [
- [
- "Character",
- "\u230d"
- ]
- ]
- },
- {
- "input": "&dollar",
- "description": "Bad named entity: dollar without a semi-colon",
- "output": [
- [
- "Character",
- "&dollar"
- ]
- ]
- },
- {
- "input": "$",
- "description": "Named entity: dollar; with a semi-colon",
- "output": [
- [
- "Character",
- "$"
- ]
- ]
- },
- {
- "input": "&dopf",
- "description": "Bad named entity: dopf without a semi-colon",
- "output": [
- [
- "Character",
- "&dopf"
- ]
- ]
- },
- {
- "input": "𝕕",
- "description": "Named entity: dopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd55"
- ]
- ]
- },
- {
- "input": "&dot",
- "description": "Bad named entity: dot without a semi-colon",
- "output": [
- [
- "Character",
- "&dot"
- ]
- ]
- },
- {
- "input": "˙",
- "description": "Named entity: dot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02d9"
- ]
- ]
- },
- {
- "input": "&doteq",
- "description": "Bad named entity: doteq without a semi-colon",
- "output": [
- [
- "Character",
- "&doteq"
- ]
- ]
- },
- {
- "input": "≐",
- "description": "Named entity: doteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2250"
- ]
- ]
- },
- {
- "input": "&doteqdot",
- "description": "Bad named entity: doteqdot without a semi-colon",
- "output": [
- [
- "Character",
- "&doteqdot"
- ]
- ]
- },
- {
- "input": "≑",
- "description": "Named entity: doteqdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2251"
- ]
- ]
- },
- {
- "input": "&dotminus",
- "description": "Bad named entity: dotminus without a semi-colon",
- "output": [
- [
- "Character",
- "&dotminus"
- ]
- ]
- },
- {
- "input": "∸",
- "description": "Named entity: dotminus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2238"
- ]
- ]
- },
- {
- "input": "&dotplus",
- "description": "Bad named entity: dotplus without a semi-colon",
- "output": [
- [
- "Character",
- "&dotplus"
- ]
- ]
- },
- {
- "input": "∔",
- "description": "Named entity: dotplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2214"
- ]
- ]
- },
- {
- "input": "&dotsquare",
- "description": "Bad named entity: dotsquare without a semi-colon",
- "output": [
- [
- "Character",
- "&dotsquare"
- ]
- ]
- },
- {
- "input": "⊡",
- "description": "Named entity: dotsquare; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a1"
- ]
- ]
- },
- {
- "input": "&doublebarwedge",
- "description": "Bad named entity: doublebarwedge without a semi-colon",
- "output": [
- [
- "Character",
- "&doublebarwedge"
- ]
- ]
- },
- {
- "input": "⌆",
- "description": "Named entity: doublebarwedge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2306"
- ]
- ]
- },
- {
- "input": "&downarrow",
- "description": "Bad named entity: downarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&downarrow"
- ]
- ]
- },
- {
- "input": "↓",
- "description": "Named entity: downarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2193"
- ]
- ]
- },
- {
- "input": "&downdownarrows",
- "description": "Bad named entity: downdownarrows without a semi-colon",
- "output": [
- [
- "Character",
- "&downdownarrows"
- ]
- ]
- },
- {
- "input": "⇊",
- "description": "Named entity: downdownarrows; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ca"
- ]
- ]
- },
- {
- "input": "&downharpoonleft",
- "description": "Bad named entity: downharpoonleft without a semi-colon",
- "output": [
- [
- "Character",
- "&downharpoonleft"
- ]
- ]
- },
- {
- "input": "⇃",
- "description": "Named entity: downharpoonleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c3"
- ]
- ]
- },
- {
- "input": "&downharpoonright",
- "description": "Bad named entity: downharpoonright without a semi-colon",
- "output": [
- [
- "Character",
- "&downharpoonright"
- ]
- ]
- },
- {
- "input": "⇂",
- "description": "Named entity: downharpoonright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c2"
- ]
- ]
- },
- {
- "input": "&drbkarow",
- "description": "Bad named entity: drbkarow without a semi-colon",
- "output": [
- [
- "Character",
- "&drbkarow"
- ]
- ]
- },
- {
- "input": "⤐",
- "description": "Named entity: drbkarow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2910"
- ]
- ]
- },
- {
- "input": "&drcorn",
- "description": "Bad named entity: drcorn without a semi-colon",
- "output": [
- [
- "Character",
- "&drcorn"
- ]
- ]
- },
- {
- "input": "⌟",
- "description": "Named entity: drcorn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u231f"
- ]
- ]
- },
- {
- "input": "&drcrop",
- "description": "Bad named entity: drcrop without a semi-colon",
- "output": [
- [
- "Character",
- "&drcrop"
- ]
- ]
- },
- {
- "input": "⌌",
- "description": "Named entity: drcrop; with a semi-colon",
- "output": [
- [
- "Character",
- "\u230c"
- ]
- ]
- },
- {
- "input": "&dscr",
- "description": "Bad named entity: dscr without a semi-colon",
- "output": [
- [
- "Character",
- "&dscr"
- ]
- ]
- },
- {
- "input": "𝒹",
- "description": "Named entity: dscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcb9"
- ]
- ]
- },
- {
- "input": "&dscy",
- "description": "Bad named entity: dscy without a semi-colon",
- "output": [
- [
- "Character",
- "&dscy"
- ]
- ]
- },
- {
- "input": "ѕ",
- "description": "Named entity: dscy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0455"
- ]
- ]
- },
- {
- "input": "&dsol",
- "description": "Bad named entity: dsol without a semi-colon",
- "output": [
- [
- "Character",
- "&dsol"
- ]
- ]
- },
- {
- "input": "⧶",
- "description": "Named entity: dsol; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29f6"
- ]
- ]
- },
- {
- "input": "&dstrok",
- "description": "Bad named entity: dstrok without a semi-colon",
- "output": [
- [
- "Character",
- "&dstrok"
- ]
- ]
- },
- {
- "input": "đ",
- "description": "Named entity: dstrok; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0111"
- ]
- ]
- },
- {
- "input": "&dtdot",
- "description": "Bad named entity: dtdot without a semi-colon",
- "output": [
- [
- "Character",
- "&dtdot"
- ]
- ]
- },
- {
- "input": "⋱",
- "description": "Named entity: dtdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f1"
- ]
- ]
- },
- {
- "input": "&dtri",
- "description": "Bad named entity: dtri without a semi-colon",
- "output": [
- [
- "Character",
- "&dtri"
- ]
- ]
- },
- {
- "input": "▿",
- "description": "Named entity: dtri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25bf"
- ]
- ]
- },
- {
- "input": "&dtrif",
- "description": "Bad named entity: dtrif without a semi-colon",
- "output": [
- [
- "Character",
- "&dtrif"
- ]
- ]
- },
- {
- "input": "▾",
- "description": "Named entity: dtrif; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25be"
- ]
- ]
- },
- {
- "input": "&duarr",
- "description": "Bad named entity: duarr without a semi-colon",
- "output": [
- [
- "Character",
- "&duarr"
- ]
- ]
- },
- {
- "input": "⇵",
- "description": "Named entity: duarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21f5"
- ]
- ]
- },
- {
- "input": "&duhar",
- "description": "Bad named entity: duhar without a semi-colon",
- "output": [
- [
- "Character",
- "&duhar"
- ]
- ]
- },
- {
- "input": "⥯",
- "description": "Named entity: duhar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u296f"
- ]
- ]
- },
- {
- "input": "&dwangle",
- "description": "Bad named entity: dwangle without a semi-colon",
- "output": [
- [
- "Character",
- "&dwangle"
- ]
- ]
- },
- {
- "input": "⦦",
- "description": "Named entity: dwangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29a6"
- ]
- ]
- },
- {
- "input": "&dzcy",
- "description": "Bad named entity: dzcy without a semi-colon",
- "output": [
- [
- "Character",
- "&dzcy"
- ]
- ]
- },
- {
- "input": "џ",
- "description": "Named entity: dzcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u045f"
- ]
- ]
- },
- {
- "input": "&dzigrarr",
- "description": "Bad named entity: dzigrarr without a semi-colon",
- "output": [
- [
- "Character",
- "&dzigrarr"
- ]
- ]
- },
- {
- "input": "⟿",
- "description": "Named entity: dzigrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27ff"
- ]
- ]
- },
- {
- "input": "&eDDot",
- "description": "Bad named entity: eDDot without a semi-colon",
- "output": [
- [
- "Character",
- "&eDDot"
- ]
- ]
- },
- {
- "input": "⩷",
- "description": "Named entity: eDDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a77"
- ]
- ]
- },
- {
- "input": "&eDot",
- "description": "Bad named entity: eDot without a semi-colon",
- "output": [
- [
- "Character",
- "&eDot"
- ]
- ]
- },
- {
- "input": "≑",
- "description": "Named entity: eDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2251"
- ]
- ]
- },
- {
- "input": "é",
- "description": "Named entity: eacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e9"
- ]
- ]
- },
- {
- "input": "é",
- "description": "Named entity: eacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e9"
- ]
- ]
- },
- {
- "input": "&easter",
- "description": "Bad named entity: easter without a semi-colon",
- "output": [
- [
- "Character",
- "&easter"
- ]
- ]
- },
- {
- "input": "⩮",
- "description": "Named entity: easter; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a6e"
- ]
- ]
- },
- {
- "input": "&ecaron",
- "description": "Bad named entity: ecaron without a semi-colon",
- "output": [
- [
- "Character",
- "&ecaron"
- ]
- ]
- },
- {
- "input": "ě",
- "description": "Named entity: ecaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u011b"
- ]
- ]
- },
- {
- "input": "&ecir",
- "description": "Bad named entity: ecir without a semi-colon",
- "output": [
- [
- "Character",
- "&ecir"
- ]
- ]
- },
- {
- "input": "≖",
- "description": "Named entity: ecir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2256"
- ]
- ]
- },
- {
- "input": "ê",
- "description": "Named entity: ecirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ea"
- ]
- ]
- },
- {
- "input": "ê",
- "description": "Named entity: ecirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ea"
- ]
- ]
- },
- {
- "input": "&ecolon",
- "description": "Bad named entity: ecolon without a semi-colon",
- "output": [
- [
- "Character",
- "&ecolon"
- ]
- ]
- },
- {
- "input": "≕",
- "description": "Named entity: ecolon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2255"
- ]
- ]
- },
- {
- "input": "&ecy",
- "description": "Bad named entity: ecy without a semi-colon",
- "output": [
- [
- "Character",
- "&ecy"
- ]
- ]
- },
- {
- "input": "э",
- "description": "Named entity: ecy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u044d"
- ]
- ]
- },
- {
- "input": "&edot",
- "description": "Bad named entity: edot without a semi-colon",
- "output": [
- [
- "Character",
- "&edot"
- ]
- ]
- },
- {
- "input": "ė",
- "description": "Named entity: edot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0117"
- ]
- ]
- },
- {
- "input": "&ee",
- "description": "Bad named entity: ee without a semi-colon",
- "output": [
- [
- "Character",
- "&ee"
- ]
- ]
- },
- {
- "input": "ⅇ",
- "description": "Named entity: ee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2147"
- ]
- ]
- },
- {
- "input": "&efDot",
- "description": "Bad named entity: efDot without a semi-colon",
- "output": [
- [
- "Character",
- "&efDot"
- ]
- ]
- },
- {
- "input": "≒",
- "description": "Named entity: efDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2252"
- ]
- ]
- },
- {
- "input": "&efr",
- "description": "Bad named entity: efr without a semi-colon",
- "output": [
- [
- "Character",
- "&efr"
- ]
- ]
- },
- {
- "input": "𝔢",
- "description": "Named entity: efr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd22"
- ]
- ]
- },
- {
- "input": "&eg",
- "description": "Bad named entity: eg without a semi-colon",
- "output": [
- [
- "Character",
- "&eg"
- ]
- ]
- },
- {
- "input": "⪚",
- "description": "Named entity: eg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a9a"
- ]
- ]
- },
- {
- "input": "è",
- "description": "Named entity: egrave without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00e8"
- ]
- ]
- },
- {
- "input": "è",
- "description": "Named entity: egrave; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00e8"
- ]
- ]
- },
- {
- "input": "&egs",
- "description": "Bad named entity: egs without a semi-colon",
- "output": [
- [
- "Character",
- "&egs"
- ]
- ]
- },
- {
- "input": "⪖",
- "description": "Named entity: egs; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a96"
- ]
- ]
- },
- {
- "input": "&egsdot",
- "description": "Bad named entity: egsdot without a semi-colon",
- "output": [
- [
- "Character",
- "&egsdot"
- ]
- ]
- },
- {
- "input": "⪘",
- "description": "Named entity: egsdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a98"
- ]
- ]
- },
- {
- "input": "&el",
- "description": "Bad named entity: el without a semi-colon",
- "output": [
- [
- "Character",
- "&el"
- ]
- ]
- },
- {
- "input": "⪙",
- "description": "Named entity: el; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a99"
- ]
- ]
- },
- {
- "input": "&elinters",
- "description": "Bad named entity: elinters without a semi-colon",
- "output": [
- [
- "Character",
- "&elinters"
- ]
- ]
- },
- {
- "input": "⏧",
- "description": "Named entity: elinters; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23e7"
- ]
- ]
- },
- {
- "input": "&ell",
- "description": "Bad named entity: ell without a semi-colon",
- "output": [
- [
- "Character",
- "&ell"
- ]
- ]
- },
- {
- "input": "ℓ",
- "description": "Named entity: ell; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2113"
- ]
- ]
- },
- {
- "input": "&els",
- "description": "Bad named entity: els without a semi-colon",
- "output": [
- [
- "Character",
- "&els"
- ]
- ]
- },
- {
- "input": "⪕",
- "description": "Named entity: els; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a95"
- ]
- ]
- },
- {
- "input": "&elsdot",
- "description": "Bad named entity: elsdot without a semi-colon",
- "output": [
- [
- "Character",
- "&elsdot"
- ]
- ]
- },
- {
- "input": "⪗",
- "description": "Named entity: elsdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a97"
- ]
- ]
- },
- {
- "input": "&emacr",
- "description": "Bad named entity: emacr without a semi-colon",
- "output": [
- [
- "Character",
- "&emacr"
- ]
- ]
- },
- {
- "input": "ē",
- "description": "Named entity: emacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0113"
- ]
- ]
- },
- {
- "input": "&empty",
- "description": "Bad named entity: empty without a semi-colon",
- "output": [
- [
- "Character",
- "&empty"
- ]
- ]
- },
- {
- "input": "∅",
- "description": "Named entity: empty; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2205"
- ]
- ]
- },
- {
- "input": "&emptyset",
- "description": "Bad named entity: emptyset without a semi-colon",
- "output": [
- [
- "Character",
- "&emptyset"
- ]
- ]
- },
- {
- "input": "∅",
- "description": "Named entity: emptyset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2205"
- ]
- ]
- },
- {
- "input": "&emptyv",
- "description": "Bad named entity: emptyv without a semi-colon",
- "output": [
- [
- "Character",
- "&emptyv"
- ]
- ]
- },
- {
- "input": "∅",
- "description": "Named entity: emptyv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2205"
- ]
- ]
- },
- {
- "input": "&emsp",
- "description": "Bad named entity: emsp without a semi-colon",
- "output": [
- [
- "Character",
- "&emsp"
- ]
- ]
- },
- {
- "input": "&emsp13",
- "description": "Bad named entity: emsp13 without a semi-colon",
- "output": [
- [
- "Character",
- "&emsp13"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: emsp13; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2004"
- ]
- ]
- },
- {
- "input": "&emsp14",
- "description": "Bad named entity: emsp14 without a semi-colon",
- "output": [
- [
- "Character",
- "&emsp14"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: emsp14; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2005"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: emsp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2003"
- ]
- ]
- },
- {
- "input": "&eng",
- "description": "Bad named entity: eng without a semi-colon",
- "output": [
- [
- "Character",
- "&eng"
- ]
- ]
- },
- {
- "input": "ŋ",
- "description": "Named entity: eng; with a semi-colon",
- "output": [
- [
- "Character",
- "\u014b"
- ]
- ]
- },
- {
- "input": "&ensp",
- "description": "Bad named entity: ensp without a semi-colon",
- "output": [
- [
- "Character",
- "&ensp"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: ensp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2002"
- ]
- ]
- },
- {
- "input": "&eogon",
- "description": "Bad named entity: eogon without a semi-colon",
- "output": [
- [
- "Character",
- "&eogon"
- ]
- ]
- },
- {
- "input": "ę",
- "description": "Named entity: eogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0119"
- ]
- ]
- },
- {
- "input": "&eopf",
- "description": "Bad named entity: eopf without a semi-colon",
- "output": [
- [
- "Character",
- "&eopf"
- ]
- ]
- },
- {
- "input": "𝕖",
- "description": "Named entity: eopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd56"
- ]
- ]
- },
- {
- "input": "&epar",
- "description": "Bad named entity: epar without a semi-colon",
- "output": [
- [
- "Character",
- "&epar"
- ]
- ]
- },
- {
- "input": "⋕",
- "description": "Named entity: epar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d5"
- ]
- ]
- },
- {
- "input": "&eparsl",
- "description": "Bad named entity: eparsl without a semi-colon",
- "output": [
- [
- "Character",
- "&eparsl"
- ]
- ]
- },
- {
- "input": "⧣",
- "description": "Named entity: eparsl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29e3"
- ]
- ]
- },
- {
- "input": "&eplus",
- "description": "Bad named entity: eplus without a semi-colon",
- "output": [
- [
- "Character",
- "&eplus"
- ]
- ]
- },
- {
- "input": "⩱",
- "description": "Named entity: eplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a71"
- ]
- ]
- },
- {
- "input": "&epsi",
- "description": "Bad named entity: epsi without a semi-colon",
- "output": [
- [
- "Character",
- "&epsi"
- ]
- ]
- },
- {
- "input": "ε",
- "description": "Named entity: epsi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b5"
- ]
- ]
- },
- {
- "input": "&epsilon",
- "description": "Bad named entity: epsilon without a semi-colon",
- "output": [
- [
- "Character",
- "&epsilon"
- ]
- ]
- },
- {
- "input": "ε",
- "description": "Named entity: epsilon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b5"
- ]
- ]
- },
- {
- "input": "&epsiv",
- "description": "Bad named entity: epsiv without a semi-colon",
- "output": [
- [
- "Character",
- "&epsiv"
- ]
- ]
- },
- {
- "input": "ϵ",
- "description": "Named entity: epsiv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f5"
- ]
- ]
- },
- {
- "input": "&eqcirc",
- "description": "Bad named entity: eqcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&eqcirc"
- ]
- ]
- },
- {
- "input": "≖",
- "description": "Named entity: eqcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2256"
- ]
- ]
- },
- {
- "input": "&eqcolon",
- "description": "Bad named entity: eqcolon without a semi-colon",
- "output": [
- [
- "Character",
- "&eqcolon"
- ]
- ]
- },
- {
- "input": "≕",
- "description": "Named entity: eqcolon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2255"
- ]
- ]
- },
- {
- "input": "&eqsim",
- "description": "Bad named entity: eqsim without a semi-colon",
- "output": [
- [
- "Character",
- "&eqsim"
- ]
- ]
- },
- {
- "input": "≂",
- "description": "Named entity: eqsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2242"
- ]
- ]
- },
- {
- "input": "&eqslantgtr",
- "description": "Bad named entity: eqslantgtr without a semi-colon",
- "output": [
- [
- "Character",
- "&eqslantgtr"
- ]
- ]
- },
- {
- "input": "⪖",
- "description": "Named entity: eqslantgtr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a96"
- ]
- ]
- },
- {
- "input": "&eqslantless",
- "description": "Bad named entity: eqslantless without a semi-colon",
- "output": [
- [
- "Character",
- "&eqslantless"
- ]
- ]
- },
- {
- "input": "⪕",
- "description": "Named entity: eqslantless; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a95"
- ]
- ]
- },
- {
- "input": "&equals",
- "description": "Bad named entity: equals without a semi-colon",
- "output": [
- [
- "Character",
- "&equals"
- ]
- ]
- },
- {
- "input": "=",
- "description": "Named entity: equals; with a semi-colon",
- "output": [
- [
- "Character",
- "="
- ]
- ]
- },
- {
- "input": "&equest",
- "description": "Bad named entity: equest without a semi-colon",
- "output": [
- [
- "Character",
- "&equest"
- ]
- ]
- },
- {
- "input": "≟",
- "description": "Named entity: equest; with a semi-colon",
- "output": [
- [
- "Character",
- "\u225f"
- ]
- ]
- },
- {
- "input": "&equiv",
- "description": "Bad named entity: equiv without a semi-colon",
- "output": [
- [
- "Character",
- "&equiv"
- ]
- ]
- },
- {
- "input": "≡",
- "description": "Named entity: equiv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2261"
- ]
- ]
- },
- {
- "input": "&equivDD",
- "description": "Bad named entity: equivDD without a semi-colon",
- "output": [
- [
- "Character",
- "&equivDD"
- ]
- ]
- },
- {
- "input": "⩸",
- "description": "Named entity: equivDD; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a78"
- ]
- ]
- },
- {
- "input": "&eqvparsl",
- "description": "Bad named entity: eqvparsl without a semi-colon",
- "output": [
- [
- "Character",
- "&eqvparsl"
- ]
- ]
- },
- {
- "input": "⧥",
- "description": "Named entity: eqvparsl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29e5"
- ]
- ]
- },
- {
- "input": "&erDot",
- "description": "Bad named entity: erDot without a semi-colon",
- "output": [
- [
- "Character",
- "&erDot"
- ]
- ]
- },
- {
- "input": "≓",
- "description": "Named entity: erDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2253"
- ]
- ]
- },
- {
- "input": "&erarr",
- "description": "Bad named entity: erarr without a semi-colon",
- "output": [
- [
- "Character",
- "&erarr"
- ]
- ]
- },
- {
- "input": "⥱",
- "description": "Named entity: erarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2971"
- ]
- ]
- },
- {
- "input": "&escr",
- "description": "Bad named entity: escr without a semi-colon",
- "output": [
- [
- "Character",
- "&escr"
- ]
- ]
- },
- {
- "input": "ℯ",
- "description": "Named entity: escr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u212f"
- ]
- ]
- },
- {
- "input": "&esdot",
- "description": "Bad named entity: esdot without a semi-colon",
- "output": [
- [
- "Character",
- "&esdot"
- ]
- ]
- },
- {
- "input": "≐",
- "description": "Named entity: esdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2250"
- ]
- ]
- },
- {
- "input": "&esim",
- "description": "Bad named entity: esim without a semi-colon",
- "output": [
- [
- "Character",
- "&esim"
- ]
- ]
- },
- {
- "input": "≂",
- "description": "Named entity: esim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2242"
- ]
- ]
- },
- {
- "input": "&eta",
- "description": "Bad named entity: eta without a semi-colon",
- "output": [
- [
- "Character",
- "&eta"
- ]
- ]
- },
- {
- "input": "η",
- "description": "Named entity: eta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b7"
- ]
- ]
- },
- {
- "input": "ð",
- "description": "Named entity: eth without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f0"
- ]
- ]
- },
- {
- "input": "ð",
- "description": "Named entity: eth; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f0"
- ]
- ]
- },
- {
- "input": "ë",
- "description": "Named entity: euml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00eb"
- ]
- ]
- },
- {
- "input": "ë",
- "description": "Named entity: euml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00eb"
- ]
- ]
- },
- {
- "input": "&euro",
- "description": "Bad named entity: euro without a semi-colon",
- "output": [
- [
- "Character",
- "&euro"
- ]
- ]
- },
- {
- "input": "€",
- "description": "Named entity: euro; with a semi-colon",
- "output": [
- [
- "Character",
- "\u20ac"
- ]
- ]
- },
- {
- "input": "&excl",
- "description": "Bad named entity: excl without a semi-colon",
- "output": [
- [
- "Character",
- "&excl"
- ]
- ]
- },
- {
- "input": "!",
- "description": "Named entity: excl; with a semi-colon",
- "output": [
- [
- "Character",
- "!"
- ]
- ]
- },
- {
- "input": "&exist",
- "description": "Bad named entity: exist without a semi-colon",
- "output": [
- [
- "Character",
- "&exist"
- ]
- ]
- },
- {
- "input": "∃",
- "description": "Named entity: exist; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2203"
- ]
- ]
- },
- {
- "input": "&expectation",
- "description": "Bad named entity: expectation without a semi-colon",
- "output": [
- [
- "Character",
- "&expectation"
- ]
- ]
- },
- {
- "input": "ℰ",
- "description": "Named entity: expectation; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2130"
- ]
- ]
- },
- {
- "input": "&exponentiale",
- "description": "Bad named entity: exponentiale without a semi-colon",
- "output": [
- [
- "Character",
- "&exponentiale"
- ]
- ]
- },
- {
- "input": "ⅇ",
- "description": "Named entity: exponentiale; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2147"
- ]
- ]
- },
- {
- "input": "&fallingdotseq",
- "description": "Bad named entity: fallingdotseq without a semi-colon",
- "output": [
- [
- "Character",
- "&fallingdotseq"
- ]
- ]
- },
- {
- "input": "≒",
- "description": "Named entity: fallingdotseq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2252"
- ]
- ]
- },
- {
- "input": "&fcy",
- "description": "Bad named entity: fcy without a semi-colon",
- "output": [
- [
- "Character",
- "&fcy"
- ]
- ]
- },
- {
- "input": "ф",
- "description": "Named entity: fcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0444"
- ]
- ]
- },
- {
- "input": "&female",
- "description": "Bad named entity: female without a semi-colon",
- "output": [
- [
- "Character",
- "&female"
- ]
- ]
- },
- {
- "input": "♀",
- "description": "Named entity: female; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2640"
- ]
- ]
- },
- {
- "input": "&ffilig",
- "description": "Bad named entity: ffilig without a semi-colon",
- "output": [
- [
- "Character",
- "&ffilig"
- ]
- ]
- },
- {
- "input": "ffi",
- "description": "Named entity: ffilig; with a semi-colon",
- "output": [
- [
- "Character",
- "\ufb03"
- ]
- ]
- },
- {
- "input": "&fflig",
- "description": "Bad named entity: fflig without a semi-colon",
- "output": [
- [
- "Character",
- "&fflig"
- ]
- ]
- },
- {
- "input": "ff",
- "description": "Named entity: fflig; with a semi-colon",
- "output": [
- [
- "Character",
- "\ufb00"
- ]
- ]
- },
- {
- "input": "&ffllig",
- "description": "Bad named entity: ffllig without a semi-colon",
- "output": [
- [
- "Character",
- "&ffllig"
- ]
- ]
- },
- {
- "input": "ffl",
- "description": "Named entity: ffllig; with a semi-colon",
- "output": [
- [
- "Character",
- "\ufb04"
- ]
- ]
- },
- {
- "input": "&ffr",
- "description": "Bad named entity: ffr without a semi-colon",
- "output": [
- [
- "Character",
- "&ffr"
- ]
- ]
- },
- {
- "input": "𝔣",
- "description": "Named entity: ffr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd23"
- ]
- ]
- },
- {
- "input": "&filig",
- "description": "Bad named entity: filig without a semi-colon",
- "output": [
- [
- "Character",
- "&filig"
- ]
- ]
- },
- {
- "input": "fi",
- "description": "Named entity: filig; with a semi-colon",
- "output": [
- [
- "Character",
- "\ufb01"
- ]
- ]
- },
- {
- "input": "&fjlig",
- "description": "Bad named entity: fjlig without a semi-colon",
- "output": [
- [
- "Character",
- "&fjlig"
- ]
- ]
- },
- {
- "input": "fj",
- "description": "Named entity: fjlig; with a semi-colon",
- "output": [
- [
- "Character",
- "fj"
- ]
- ]
- },
- {
- "input": "&flat",
- "description": "Bad named entity: flat without a semi-colon",
- "output": [
- [
- "Character",
- "&flat"
- ]
- ]
- },
- {
- "input": "♭",
- "description": "Named entity: flat; with a semi-colon",
- "output": [
- [
- "Character",
- "\u266d"
- ]
- ]
- },
- {
- "input": "&fllig",
- "description": "Bad named entity: fllig without a semi-colon",
- "output": [
- [
- "Character",
- "&fllig"
- ]
- ]
- },
- {
- "input": "fl",
- "description": "Named entity: fllig; with a semi-colon",
- "output": [
- [
- "Character",
- "\ufb02"
- ]
- ]
- },
- {
- "input": "&fltns",
- "description": "Bad named entity: fltns without a semi-colon",
- "output": [
- [
- "Character",
- "&fltns"
- ]
- ]
- },
- {
- "input": "▱",
- "description": "Named entity: fltns; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b1"
- ]
- ]
- },
- {
- "input": "&fnof",
- "description": "Bad named entity: fnof without a semi-colon",
- "output": [
- [
- "Character",
- "&fnof"
- ]
- ]
- },
- {
- "input": "ƒ",
- "description": "Named entity: fnof; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0192"
- ]
- ]
- },
- {
- "input": "&fopf",
- "description": "Bad named entity: fopf without a semi-colon",
- "output": [
- [
- "Character",
- "&fopf"
- ]
- ]
- },
- {
- "input": "𝕗",
- "description": "Named entity: fopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd57"
- ]
- ]
- },
- {
- "input": "&forall",
- "description": "Bad named entity: forall without a semi-colon",
- "output": [
- [
- "Character",
- "&forall"
- ]
- ]
- },
- {
- "input": "∀",
- "description": "Named entity: forall; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2200"
- ]
- ]
- },
- {
- "input": "&fork",
- "description": "Bad named entity: fork without a semi-colon",
- "output": [
- [
- "Character",
- "&fork"
- ]
- ]
- },
- {
- "input": "⋔",
- "description": "Named entity: fork; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d4"
- ]
- ]
- },
- {
- "input": "&forkv",
- "description": "Bad named entity: forkv without a semi-colon",
- "output": [
- [
- "Character",
- "&forkv"
- ]
- ]
- },
- {
- "input": "⫙",
- "description": "Named entity: forkv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad9"
- ]
- ]
- },
- {
- "input": "&fpartint",
- "description": "Bad named entity: fpartint without a semi-colon",
- "output": [
- [
- "Character",
- "&fpartint"
- ]
- ]
- },
- {
- "input": "⨍",
- "description": "Named entity: fpartint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a0d"
- ]
- ]
- },
- {
- "input": "½",
- "description": "Named entity: frac12 without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00bd"
- ]
- ]
- },
- {
- "input": "½",
- "description": "Named entity: frac12; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00bd"
- ]
- ]
- },
- {
- "input": "&frac13",
- "description": "Bad named entity: frac13 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac13"
- ]
- ]
- },
- {
- "input": "⅓",
- "description": "Named entity: frac13; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2153"
- ]
- ]
- },
- {
- "input": "¼",
- "description": "Named entity: frac14 without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00bc"
- ]
- ]
- },
- {
- "input": "¼",
- "description": "Named entity: frac14; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00bc"
- ]
- ]
- },
- {
- "input": "&frac15",
- "description": "Bad named entity: frac15 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac15"
- ]
- ]
- },
- {
- "input": "⅕",
- "description": "Named entity: frac15; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2155"
- ]
- ]
- },
- {
- "input": "&frac16",
- "description": "Bad named entity: frac16 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac16"
- ]
- ]
- },
- {
- "input": "⅙",
- "description": "Named entity: frac16; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2159"
- ]
- ]
- },
- {
- "input": "&frac18",
- "description": "Bad named entity: frac18 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac18"
- ]
- ]
- },
- {
- "input": "⅛",
- "description": "Named entity: frac18; with a semi-colon",
- "output": [
- [
- "Character",
- "\u215b"
- ]
- ]
- },
- {
- "input": "&frac23",
- "description": "Bad named entity: frac23 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac23"
- ]
- ]
- },
- {
- "input": "⅔",
- "description": "Named entity: frac23; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2154"
- ]
- ]
- },
- {
- "input": "&frac25",
- "description": "Bad named entity: frac25 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac25"
- ]
- ]
- },
- {
- "input": "⅖",
- "description": "Named entity: frac25; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2156"
- ]
- ]
- },
- {
- "input": "¾",
- "description": "Named entity: frac34 without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00be"
- ]
- ]
- },
- {
- "input": "¾",
- "description": "Named entity: frac34; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00be"
- ]
- ]
- },
- {
- "input": "&frac35",
- "description": "Bad named entity: frac35 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac35"
- ]
- ]
- },
- {
- "input": "⅗",
- "description": "Named entity: frac35; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2157"
- ]
- ]
- },
- {
- "input": "&frac38",
- "description": "Bad named entity: frac38 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac38"
- ]
- ]
- },
- {
- "input": "⅜",
- "description": "Named entity: frac38; with a semi-colon",
- "output": [
- [
- "Character",
- "\u215c"
- ]
- ]
- },
- {
- "input": "&frac45",
- "description": "Bad named entity: frac45 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac45"
- ]
- ]
- },
- {
- "input": "⅘",
- "description": "Named entity: frac45; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2158"
- ]
- ]
- },
- {
- "input": "&frac56",
- "description": "Bad named entity: frac56 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac56"
- ]
- ]
- },
- {
- "input": "⅚",
- "description": "Named entity: frac56; with a semi-colon",
- "output": [
- [
- "Character",
- "\u215a"
- ]
- ]
- },
- {
- "input": "&frac58",
- "description": "Bad named entity: frac58 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac58"
- ]
- ]
- },
- {
- "input": "⅝",
- "description": "Named entity: frac58; with a semi-colon",
- "output": [
- [
- "Character",
- "\u215d"
- ]
- ]
- },
- {
- "input": "&frac78",
- "description": "Bad named entity: frac78 without a semi-colon",
- "output": [
- [
- "Character",
- "&frac78"
- ]
- ]
- },
- {
- "input": "⅞",
- "description": "Named entity: frac78; with a semi-colon",
- "output": [
- [
- "Character",
- "\u215e"
- ]
- ]
- },
- {
- "input": "&frasl",
- "description": "Bad named entity: frasl without a semi-colon",
- "output": [
- [
- "Character",
- "&frasl"
- ]
- ]
- },
- {
- "input": "⁄",
- "description": "Named entity: frasl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2044"
- ]
- ]
- },
- {
- "input": "&frown",
- "description": "Bad named entity: frown without a semi-colon",
- "output": [
- [
- "Character",
- "&frown"
- ]
- ]
- },
- {
- "input": "⌢",
- "description": "Named entity: frown; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2322"
- ]
- ]
- },
- {
- "input": "&fscr",
- "description": "Bad named entity: fscr without a semi-colon",
- "output": [
- [
- "Character",
- "&fscr"
- ]
- ]
- },
- {
- "input": "𝒻",
- "description": "Named entity: fscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcbb"
- ]
- ]
- },
- {
- "input": "&gE",
- "description": "Bad named entity: gE without a semi-colon",
- "output": [
- [
- "Character",
- "&gE"
- ]
- ]
- },
- {
- "input": "≧",
- "description": "Named entity: gE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2267"
- ]
- ]
- },
- {
- "input": "&gEl",
- "description": "Bad named entity: gEl without a semi-colon",
- "output": [
- [
- "Character",
- "&gEl"
- ]
- ]
- },
- {
- "input": "⪌",
- "description": "Named entity: gEl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8c"
- ]
- ]
- },
- {
- "input": "&gacute",
- "description": "Bad named entity: gacute without a semi-colon",
- "output": [
- [
- "Character",
- "&gacute"
- ]
- ]
- },
- {
- "input": "ǵ",
- "description": "Named entity: gacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u01f5"
- ]
- ]
- },
- {
- "input": "&gamma",
- "description": "Bad named entity: gamma without a semi-colon",
- "output": [
- [
- "Character",
- "&gamma"
- ]
- ]
- },
- {
- "input": "γ",
- "description": "Named entity: gamma; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b3"
- ]
- ]
- },
- {
- "input": "&gammad",
- "description": "Bad named entity: gammad without a semi-colon",
- "output": [
- [
- "Character",
- "&gammad"
- ]
- ]
- },
- {
- "input": "ϝ",
- "description": "Named entity: gammad; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03dd"
- ]
- ]
- },
- {
- "input": "&gap",
- "description": "Bad named entity: gap without a semi-colon",
- "output": [
- [
- "Character",
- "&gap"
- ]
- ]
- },
- {
- "input": "⪆",
- "description": "Named entity: gap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a86"
- ]
- ]
- },
- {
- "input": "&gbreve",
- "description": "Bad named entity: gbreve without a semi-colon",
- "output": [
- [
- "Character",
- "&gbreve"
- ]
- ]
- },
- {
- "input": "ğ",
- "description": "Named entity: gbreve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u011f"
- ]
- ]
- },
- {
- "input": "&gcirc",
- "description": "Bad named entity: gcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&gcirc"
- ]
- ]
- },
- {
- "input": "ĝ",
- "description": "Named entity: gcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u011d"
- ]
- ]
- },
- {
- "input": "&gcy",
- "description": "Bad named entity: gcy without a semi-colon",
- "output": [
- [
- "Character",
- "&gcy"
- ]
- ]
- },
- {
- "input": "г",
- "description": "Named entity: gcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0433"
- ]
- ]
- },
- {
- "input": "&gdot",
- "description": "Bad named entity: gdot without a semi-colon",
- "output": [
- [
- "Character",
- "&gdot"
- ]
- ]
- },
- {
- "input": "ġ",
- "description": "Named entity: gdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0121"
- ]
- ]
- },
- {
- "input": "&ge",
- "description": "Bad named entity: ge without a semi-colon",
- "output": [
- [
- "Character",
- "&ge"
- ]
- ]
- },
- {
- "input": "≥",
- "description": "Named entity: ge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2265"
- ]
- ]
- },
- {
- "input": "&gel",
- "description": "Bad named entity: gel without a semi-colon",
- "output": [
- [
- "Character",
- "&gel"
- ]
- ]
- },
- {
- "input": "⋛",
- "description": "Named entity: gel; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22db"
- ]
- ]
- },
- {
- "input": "&geq",
- "description": "Bad named entity: geq without a semi-colon",
- "output": [
- [
- "Character",
- "&geq"
- ]
- ]
- },
- {
- "input": "≥",
- "description": "Named entity: geq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2265"
- ]
- ]
- },
- {
- "input": "&geqq",
- "description": "Bad named entity: geqq without a semi-colon",
- "output": [
- [
- "Character",
- "&geqq"
- ]
- ]
- },
- {
- "input": "≧",
- "description": "Named entity: geqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2267"
- ]
- ]
- },
- {
- "input": "&geqslant",
- "description": "Bad named entity: geqslant without a semi-colon",
- "output": [
- [
- "Character",
- "&geqslant"
- ]
- ]
- },
- {
- "input": "⩾",
- "description": "Named entity: geqslant; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7e"
- ]
- ]
- },
- {
- "input": "&ges",
- "description": "Bad named entity: ges without a semi-colon",
- "output": [
- [
- "Character",
- "&ges"
- ]
- ]
- },
- {
- "input": "⩾",
- "description": "Named entity: ges; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7e"
- ]
- ]
- },
- {
- "input": "&gescc",
- "description": "Bad named entity: gescc without a semi-colon",
- "output": [
- [
- "Character",
- "&gescc"
- ]
- ]
- },
- {
- "input": "⪩",
- "description": "Named entity: gescc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa9"
- ]
- ]
- },
- {
- "input": "&gesdot",
- "description": "Bad named entity: gesdot without a semi-colon",
- "output": [
- [
- "Character",
- "&gesdot"
- ]
- ]
- },
- {
- "input": "⪀",
- "description": "Named entity: gesdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a80"
- ]
- ]
- },
- {
- "input": "&gesdoto",
- "description": "Bad named entity: gesdoto without a semi-colon",
- "output": [
- [
- "Character",
- "&gesdoto"
- ]
- ]
- },
- {
- "input": "⪂",
- "description": "Named entity: gesdoto; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a82"
- ]
- ]
- },
- {
- "input": "&gesdotol",
- "description": "Bad named entity: gesdotol without a semi-colon",
- "output": [
- [
- "Character",
- "&gesdotol"
- ]
- ]
- },
- {
- "input": "⪄",
- "description": "Named entity: gesdotol; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a84"
- ]
- ]
- },
- {
- "input": "&gesl",
- "description": "Bad named entity: gesl without a semi-colon",
- "output": [
- [
- "Character",
- "&gesl"
- ]
- ]
- },
- {
- "input": "⋛︀",
- "description": "Named entity: gesl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22db\ufe00"
- ]
- ]
- },
- {
- "input": "&gesles",
- "description": "Bad named entity: gesles without a semi-colon",
- "output": [
- [
- "Character",
- "&gesles"
- ]
- ]
- },
- {
- "input": "⪔",
- "description": "Named entity: gesles; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a94"
- ]
- ]
- },
- {
- "input": "&gfr",
- "description": "Bad named entity: gfr without a semi-colon",
- "output": [
- [
- "Character",
- "&gfr"
- ]
- ]
- },
- {
- "input": "𝔤",
- "description": "Named entity: gfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd24"
- ]
- ]
- },
- {
- "input": "&gg",
- "description": "Bad named entity: gg without a semi-colon",
- "output": [
- [
- "Character",
- "&gg"
- ]
- ]
- },
- {
- "input": "≫",
- "description": "Named entity: gg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226b"
- ]
- ]
- },
- {
- "input": "&ggg",
- "description": "Bad named entity: ggg without a semi-colon",
- "output": [
- [
- "Character",
- "&ggg"
- ]
- ]
- },
- {
- "input": "⋙",
- "description": "Named entity: ggg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d9"
- ]
- ]
- },
- {
- "input": "&gimel",
- "description": "Bad named entity: gimel without a semi-colon",
- "output": [
- [
- "Character",
- "&gimel"
- ]
- ]
- },
- {
- "input": "ℷ",
- "description": "Named entity: gimel; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2137"
- ]
- ]
- },
- {
- "input": "&gjcy",
- "description": "Bad named entity: gjcy without a semi-colon",
- "output": [
- [
- "Character",
- "&gjcy"
- ]
- ]
- },
- {
- "input": "ѓ",
- "description": "Named entity: gjcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0453"
- ]
- ]
- },
- {
- "input": "&gl",
- "description": "Bad named entity: gl without a semi-colon",
- "output": [
- [
- "Character",
- "&gl"
- ]
- ]
- },
- {
- "input": "≷",
- "description": "Named entity: gl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2277"
- ]
- ]
- },
- {
- "input": "&glE",
- "description": "Bad named entity: glE without a semi-colon",
- "output": [
- [
- "Character",
- "&glE"
- ]
- ]
- },
- {
- "input": "⪒",
- "description": "Named entity: glE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a92"
- ]
- ]
- },
- {
- "input": "&gla",
- "description": "Bad named entity: gla without a semi-colon",
- "output": [
- [
- "Character",
- "&gla"
- ]
- ]
- },
- {
- "input": "⪥",
- "description": "Named entity: gla; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa5"
- ]
- ]
- },
- {
- "input": "&glj",
- "description": "Bad named entity: glj without a semi-colon",
- "output": [
- [
- "Character",
- "&glj"
- ]
- ]
- },
- {
- "input": "⪤",
- "description": "Named entity: glj; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa4"
- ]
- ]
- },
- {
- "input": "&gnE",
- "description": "Bad named entity: gnE without a semi-colon",
- "output": [
- [
- "Character",
- "&gnE"
- ]
- ]
- },
- {
- "input": "≩",
- "description": "Named entity: gnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2269"
- ]
- ]
- },
- {
- "input": "&gnap",
- "description": "Bad named entity: gnap without a semi-colon",
- "output": [
- [
- "Character",
- "&gnap"
- ]
- ]
- },
- {
- "input": "⪊",
- "description": "Named entity: gnap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8a"
- ]
- ]
- },
- {
- "input": "&gnapprox",
- "description": "Bad named entity: gnapprox without a semi-colon",
- "output": [
- [
- "Character",
- "&gnapprox"
- ]
- ]
- },
- {
- "input": "⪊",
- "description": "Named entity: gnapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8a"
- ]
- ]
- },
- {
- "input": "&gne",
- "description": "Bad named entity: gne without a semi-colon",
- "output": [
- [
- "Character",
- "&gne"
- ]
- ]
- },
- {
- "input": "⪈",
- "description": "Named entity: gne; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a88"
- ]
- ]
- },
- {
- "input": "&gneq",
- "description": "Bad named entity: gneq without a semi-colon",
- "output": [
- [
- "Character",
- "&gneq"
- ]
- ]
- },
- {
- "input": "⪈",
- "description": "Named entity: gneq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a88"
- ]
- ]
- },
- {
- "input": "&gneqq",
- "description": "Bad named entity: gneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&gneqq"
- ]
- ]
- },
- {
- "input": "≩",
- "description": "Named entity: gneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2269"
- ]
- ]
- },
- {
- "input": "&gnsim",
- "description": "Bad named entity: gnsim without a semi-colon",
- "output": [
- [
- "Character",
- "&gnsim"
- ]
- ]
- },
- {
- "input": "⋧",
- "description": "Named entity: gnsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e7"
- ]
- ]
- },
- {
- "input": "&gopf",
- "description": "Bad named entity: gopf without a semi-colon",
- "output": [
- [
- "Character",
- "&gopf"
- ]
- ]
- },
- {
- "input": "𝕘",
- "description": "Named entity: gopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd58"
- ]
- ]
- },
- {
- "input": "&grave",
- "description": "Bad named entity: grave without a semi-colon",
- "output": [
- [
- "Character",
- "&grave"
- ]
- ]
- },
- {
- "input": "`",
- "description": "Named entity: grave; with a semi-colon",
- "output": [
- [
- "Character",
- "`"
- ]
- ]
- },
- {
- "input": "&gscr",
- "description": "Bad named entity: gscr without a semi-colon",
- "output": [
- [
- "Character",
- "&gscr"
- ]
- ]
- },
- {
- "input": "ℊ",
- "description": "Named entity: gscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210a"
- ]
- ]
- },
- {
- "input": "&gsim",
- "description": "Bad named entity: gsim without a semi-colon",
- "output": [
- [
- "Character",
- "&gsim"
- ]
- ]
- },
- {
- "input": "≳",
- "description": "Named entity: gsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2273"
- ]
- ]
- },
- {
- "input": "&gsime",
- "description": "Bad named entity: gsime without a semi-colon",
- "output": [
- [
- "Character",
- "&gsime"
- ]
- ]
- },
- {
- "input": "⪎",
- "description": "Named entity: gsime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8e"
- ]
- ]
- },
- {
- "input": "&gsiml",
- "description": "Bad named entity: gsiml without a semi-colon",
- "output": [
- [
- "Character",
- "&gsiml"
- ]
- ]
- },
- {
- "input": "⪐",
- "description": "Named entity: gsiml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a90"
- ]
- ]
- },
- {
- "input": ">",
- "description": "Named entity: gt without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- ">"
- ]
- ]
- },
- {
- "input": ">",
- "description": "Named entity: gt; with a semi-colon",
- "output": [
- [
- "Character",
- ">"
- ]
- ]
- },
- {
- "input": "⪧",
- "description": "Named entity: gtcc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa7"
- ]
- ]
- },
- {
- "input": "⩺",
- "description": "Named entity: gtcir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7a"
- ]
- ]
- },
- {
- "input": "⋗",
- "description": "Named entity: gtdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d7"
- ]
- ]
- },
- {
- "input": "⦕",
- "description": "Named entity: gtlPar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2995"
- ]
- ]
- },
- {
- "input": "⩼",
- "description": "Named entity: gtquest; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7c"
- ]
- ]
- },
- {
- "input": "⪆",
- "description": "Named entity: gtrapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a86"
- ]
- ]
- },
- {
- "input": "⥸",
- "description": "Named entity: gtrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2978"
- ]
- ]
- },
- {
- "input": "⋗",
- "description": "Named entity: gtrdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d7"
- ]
- ]
- },
- {
- "input": "⋛",
- "description": "Named entity: gtreqless; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22db"
- ]
- ]
- },
- {
- "input": "⪌",
- "description": "Named entity: gtreqqless; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8c"
- ]
- ]
- },
- {
- "input": "≷",
- "description": "Named entity: gtrless; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2277"
- ]
- ]
- },
- {
- "input": "≳",
- "description": "Named entity: gtrsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2273"
- ]
- ]
- },
- {
- "input": "&gvertneqq",
- "description": "Bad named entity: gvertneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&gvertneqq"
- ]
- ]
- },
- {
- "input": "≩︀",
- "description": "Named entity: gvertneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2269\ufe00"
- ]
- ]
- },
- {
- "input": "&gvnE",
- "description": "Bad named entity: gvnE without a semi-colon",
- "output": [
- [
- "Character",
- "&gvnE"
- ]
- ]
- },
- {
- "input": "≩︀",
- "description": "Named entity: gvnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2269\ufe00"
- ]
- ]
- },
- {
- "input": "&hArr",
- "description": "Bad named entity: hArr without a semi-colon",
- "output": [
- [
- "Character",
- "&hArr"
- ]
- ]
- },
- {
- "input": "⇔",
- "description": "Named entity: hArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d4"
- ]
- ]
- },
- {
- "input": "&hairsp",
- "description": "Bad named entity: hairsp without a semi-colon",
- "output": [
- [
- "Character",
- "&hairsp"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: hairsp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200a"
- ]
- ]
- },
- {
- "input": "&half",
- "description": "Bad named entity: half without a semi-colon",
- "output": [
- [
- "Character",
- "&half"
- ]
- ]
- },
- {
- "input": "½",
- "description": "Named entity: half; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00bd"
- ]
- ]
- },
- {
- "input": "&hamilt",
- "description": "Bad named entity: hamilt without a semi-colon",
- "output": [
- [
- "Character",
- "&hamilt"
- ]
- ]
- },
- {
- "input": "ℋ",
- "description": "Named entity: hamilt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210b"
- ]
- ]
- },
- {
- "input": "&hardcy",
- "description": "Bad named entity: hardcy without a semi-colon",
- "output": [
- [
- "Character",
- "&hardcy"
- ]
- ]
- },
- {
- "input": "ъ",
- "description": "Named entity: hardcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u044a"
- ]
- ]
- },
- {
- "input": "&harr",
- "description": "Bad named entity: harr without a semi-colon",
- "output": [
- [
- "Character",
- "&harr"
- ]
- ]
- },
- {
- "input": "↔",
- "description": "Named entity: harr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2194"
- ]
- ]
- },
- {
- "input": "&harrcir",
- "description": "Bad named entity: harrcir without a semi-colon",
- "output": [
- [
- "Character",
- "&harrcir"
- ]
- ]
- },
- {
- "input": "⥈",
- "description": "Named entity: harrcir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2948"
- ]
- ]
- },
- {
- "input": "&harrw",
- "description": "Bad named entity: harrw without a semi-colon",
- "output": [
- [
- "Character",
- "&harrw"
- ]
- ]
- },
- {
- "input": "↭",
- "description": "Named entity: harrw; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ad"
- ]
- ]
- },
- {
- "input": "&hbar",
- "description": "Bad named entity: hbar without a semi-colon",
- "output": [
- [
- "Character",
- "&hbar"
- ]
- ]
- },
- {
- "input": "ℏ",
- "description": "Named entity: hbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210f"
- ]
- ]
- },
- {
- "input": "&hcirc",
- "description": "Bad named entity: hcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&hcirc"
- ]
- ]
- },
- {
- "input": "ĥ",
- "description": "Named entity: hcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0125"
- ]
- ]
- },
- {
- "input": "&hearts",
- "description": "Bad named entity: hearts without a semi-colon",
- "output": [
- [
- "Character",
- "&hearts"
- ]
- ]
- },
- {
- "input": "♥",
- "description": "Named entity: hearts; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2665"
- ]
- ]
- },
- {
- "input": "&heartsuit",
- "description": "Bad named entity: heartsuit without a semi-colon",
- "output": [
- [
- "Character",
- "&heartsuit"
- ]
- ]
- },
- {
- "input": "♥",
- "description": "Named entity: heartsuit; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2665"
- ]
- ]
- },
- {
- "input": "&hellip",
- "description": "Bad named entity: hellip without a semi-colon",
- "output": [
- [
- "Character",
- "&hellip"
- ]
- ]
- },
- {
- "input": "…",
- "description": "Named entity: hellip; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2026"
- ]
- ]
- },
- {
- "input": "&hercon",
- "description": "Bad named entity: hercon without a semi-colon",
- "output": [
- [
- "Character",
- "&hercon"
- ]
- ]
- },
- {
- "input": "⊹",
- "description": "Named entity: hercon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b9"
- ]
- ]
- },
- {
- "input": "&hfr",
- "description": "Bad named entity: hfr without a semi-colon",
- "output": [
- [
- "Character",
- "&hfr"
- ]
- ]
- },
- {
- "input": "𝔥",
- "description": "Named entity: hfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd25"
- ]
- ]
- },
- {
- "input": "&hksearow",
- "description": "Bad named entity: hksearow without a semi-colon",
- "output": [
- [
- "Character",
- "&hksearow"
- ]
- ]
- },
- {
- "input": "⤥",
- "description": "Named entity: hksearow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2925"
- ]
- ]
- },
- {
- "input": "&hkswarow",
- "description": "Bad named entity: hkswarow without a semi-colon",
- "output": [
- [
- "Character",
- "&hkswarow"
- ]
- ]
- },
- {
- "input": "⤦",
- "description": "Named entity: hkswarow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2926"
- ]
- ]
- },
- {
- "input": "&hoarr",
- "description": "Bad named entity: hoarr without a semi-colon",
- "output": [
- [
- "Character",
- "&hoarr"
- ]
- ]
- },
- {
- "input": "⇿",
- "description": "Named entity: hoarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ff"
- ]
- ]
- },
- {
- "input": "&homtht",
- "description": "Bad named entity: homtht without a semi-colon",
- "output": [
- [
- "Character",
- "&homtht"
- ]
- ]
- },
- {
- "input": "∻",
- "description": "Named entity: homtht; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223b"
- ]
- ]
- },
- {
- "input": "&hookleftarrow",
- "description": "Bad named entity: hookleftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&hookleftarrow"
- ]
- ]
- },
- {
- "input": "↩",
- "description": "Named entity: hookleftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a9"
- ]
- ]
- },
- {
- "input": "&hookrightarrow",
- "description": "Bad named entity: hookrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&hookrightarrow"
- ]
- ]
- },
- {
- "input": "↪",
- "description": "Named entity: hookrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21aa"
- ]
- ]
- },
- {
- "input": "&hopf",
- "description": "Bad named entity: hopf without a semi-colon",
- "output": [
- [
- "Character",
- "&hopf"
- ]
- ]
- },
- {
- "input": "𝕙",
- "description": "Named entity: hopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd59"
- ]
- ]
- },
- {
- "input": "&horbar",
- "description": "Bad named entity: horbar without a semi-colon",
- "output": [
- [
- "Character",
- "&horbar"
- ]
- ]
- },
- {
- "input": "―",
- "description": "Named entity: horbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2015"
- ]
- ]
- },
- {
- "input": "&hscr",
- "description": "Bad named entity: hscr without a semi-colon",
- "output": [
- [
- "Character",
- "&hscr"
- ]
- ]
- },
- {
- "input": "𝒽",
- "description": "Named entity: hscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcbd"
- ]
- ]
- },
- {
- "input": "&hslash",
- "description": "Bad named entity: hslash without a semi-colon",
- "output": [
- [
- "Character",
- "&hslash"
- ]
- ]
- },
- {
- "input": "ℏ",
- "description": "Named entity: hslash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210f"
- ]
- ]
- },
- {
- "input": "&hstrok",
- "description": "Bad named entity: hstrok without a semi-colon",
- "output": [
- [
- "Character",
- "&hstrok"
- ]
- ]
- },
- {
- "input": "ħ",
- "description": "Named entity: hstrok; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0127"
- ]
- ]
- },
- {
- "input": "&hybull",
- "description": "Bad named entity: hybull without a semi-colon",
- "output": [
- [
- "Character",
- "&hybull"
- ]
- ]
- },
- {
- "input": "⁃",
- "description": "Named entity: hybull; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2043"
- ]
- ]
- },
- {
- "input": "&hyphen",
- "description": "Bad named entity: hyphen without a semi-colon",
- "output": [
- [
- "Character",
- "&hyphen"
- ]
- ]
- },
- {
- "input": "‐",
- "description": "Named entity: hyphen; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2010"
- ]
- ]
- },
- {
- "input": "í",
- "description": "Named entity: iacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ed"
- ]
- ]
- },
- {
- "input": "í",
- "description": "Named entity: iacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ed"
- ]
- ]
- },
- {
- "input": "&ic",
- "description": "Bad named entity: ic without a semi-colon",
- "output": [
- [
- "Character",
- "&ic"
- ]
- ]
- },
- {
- "input": "⁣",
- "description": "Named entity: ic; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2063"
- ]
- ]
- },
- {
- "input": "î",
- "description": "Named entity: icirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ee"
- ]
- ]
- },
- {
- "input": "î",
- "description": "Named entity: icirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ee"
- ]
- ]
- },
- {
- "input": "&icy",
- "description": "Bad named entity: icy without a semi-colon",
- "output": [
- [
- "Character",
- "&icy"
- ]
- ]
- },
- {
- "input": "и",
- "description": "Named entity: icy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0438"
- ]
- ]
- },
- {
- "input": "&iecy",
- "description": "Bad named entity: iecy without a semi-colon",
- "output": [
- [
- "Character",
- "&iecy"
- ]
- ]
- },
- {
- "input": "е",
- "description": "Named entity: iecy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0435"
- ]
- ]
- },
- {
- "input": "¡",
- "description": "Named entity: iexcl without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a1"
- ]
- ]
- },
- {
- "input": "¡",
- "description": "Named entity: iexcl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a1"
- ]
- ]
- },
- {
- "input": "&iff",
- "description": "Bad named entity: iff without a semi-colon",
- "output": [
- [
- "Character",
- "&iff"
- ]
- ]
- },
- {
- "input": "⇔",
- "description": "Named entity: iff; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d4"
- ]
- ]
- },
- {
- "input": "&ifr",
- "description": "Bad named entity: ifr without a semi-colon",
- "output": [
- [
- "Character",
- "&ifr"
- ]
- ]
- },
- {
- "input": "𝔦",
- "description": "Named entity: ifr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd26"
- ]
- ]
- },
- {
- "input": "ì",
- "description": "Named entity: igrave without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ec"
- ]
- ]
- },
- {
- "input": "ì",
- "description": "Named entity: igrave; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ec"
- ]
- ]
- },
- {
- "input": "&ii",
- "description": "Bad named entity: ii without a semi-colon",
- "output": [
- [
- "Character",
- "&ii"
- ]
- ]
- },
- {
- "input": "ⅈ",
- "description": "Named entity: ii; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2148"
- ]
- ]
- },
- {
- "input": "&iiiint",
- "description": "Bad named entity: iiiint without a semi-colon",
- "output": [
- [
- "Character",
- "&iiiint"
- ]
- ]
- },
- {
- "input": "⨌",
- "description": "Named entity: iiiint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a0c"
- ]
- ]
- },
- {
- "input": "&iiint",
- "description": "Bad named entity: iiint without a semi-colon",
- "output": [
- [
- "Character",
- "&iiint"
- ]
- ]
- },
- {
- "input": "∭",
- "description": "Named entity: iiint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222d"
- ]
- ]
- },
- {
- "input": "&iinfin",
- "description": "Bad named entity: iinfin without a semi-colon",
- "output": [
- [
- "Character",
- "&iinfin"
- ]
- ]
- },
- {
- "input": "⧜",
- "description": "Named entity: iinfin; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29dc"
- ]
- ]
- },
- {
- "input": "&iiota",
- "description": "Bad named entity: iiota without a semi-colon",
- "output": [
- [
- "Character",
- "&iiota"
- ]
- ]
- },
- {
- "input": "℩",
- "description": "Named entity: iiota; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2129"
- ]
- ]
- },
- {
- "input": "&ijlig",
- "description": "Bad named entity: ijlig without a semi-colon",
- "output": [
- [
- "Character",
- "&ijlig"
- ]
- ]
- },
- {
- "input": "ij",
- "description": "Named entity: ijlig; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0133"
- ]
- ]
- },
- {
- "input": "&imacr",
- "description": "Bad named entity: imacr without a semi-colon",
- "output": [
- [
- "Character",
- "&imacr"
- ]
- ]
- },
- {
- "input": "ī",
- "description": "Named entity: imacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u012b"
- ]
- ]
- },
- {
- "input": "&image",
- "description": "Bad named entity: image without a semi-colon",
- "output": [
- [
- "Character",
- "&image"
- ]
- ]
- },
- {
- "input": "ℑ",
- "description": "Named entity: image; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2111"
- ]
- ]
- },
- {
- "input": "&imagline",
- "description": "Bad named entity: imagline without a semi-colon",
- "output": [
- [
- "Character",
- "&imagline"
- ]
- ]
- },
- {
- "input": "ℐ",
- "description": "Named entity: imagline; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2110"
- ]
- ]
- },
- {
- "input": "&imagpart",
- "description": "Bad named entity: imagpart without a semi-colon",
- "output": [
- [
- "Character",
- "&imagpart"
- ]
- ]
- },
- {
- "input": "ℑ",
- "description": "Named entity: imagpart; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2111"
- ]
- ]
- },
- {
- "input": "&imath",
- "description": "Bad named entity: imath without a semi-colon",
- "output": [
- [
- "Character",
- "&imath"
- ]
- ]
- },
- {
- "input": "ı",
- "description": "Named entity: imath; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0131"
- ]
- ]
- },
- {
- "input": "&imof",
- "description": "Bad named entity: imof without a semi-colon",
- "output": [
- [
- "Character",
- "&imof"
- ]
- ]
- },
- {
- "input": "⊷",
- "description": "Named entity: imof; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b7"
- ]
- ]
- },
- {
- "input": "&imped",
- "description": "Bad named entity: imped without a semi-colon",
- "output": [
- [
- "Character",
- "&imped"
- ]
- ]
- },
- {
- "input": "Ƶ",
- "description": "Named entity: imped; with a semi-colon",
- "output": [
- [
- "Character",
- "\u01b5"
- ]
- ]
- },
- {
- "input": "&in",
- "description": "Bad named entity: in without a semi-colon",
- "output": [
- [
- "Character",
- "&in"
- ]
- ]
- },
- {
- "input": "∈",
- "description": "Named entity: in; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2208"
- ]
- ]
- },
- {
- "input": "&incare",
- "description": "Bad named entity: incare without a semi-colon",
- "output": [
- [
- "Character",
- "&incare"
- ]
- ]
- },
- {
- "input": "℅",
- "description": "Named entity: incare; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2105"
- ]
- ]
- },
- {
- "input": "&infin",
- "description": "Bad named entity: infin without a semi-colon",
- "output": [
- [
- "Character",
- "&infin"
- ]
- ]
- },
- {
- "input": "∞",
- "description": "Named entity: infin; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221e"
- ]
- ]
- },
- {
- "input": "&infintie",
- "description": "Bad named entity: infintie without a semi-colon",
- "output": [
- [
- "Character",
- "&infintie"
- ]
- ]
- },
- {
- "input": "⧝",
- "description": "Named entity: infintie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29dd"
- ]
- ]
- },
- {
- "input": "&inodot",
- "description": "Bad named entity: inodot without a semi-colon",
- "output": [
- [
- "Character",
- "&inodot"
- ]
- ]
- },
- {
- "input": "ı",
- "description": "Named entity: inodot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0131"
- ]
- ]
- },
- {
- "input": "&int",
- "description": "Bad named entity: int without a semi-colon",
- "output": [
- [
- "Character",
- "&int"
- ]
- ]
- },
- {
- "input": "∫",
- "description": "Named entity: int; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222b"
- ]
- ]
- },
- {
- "input": "&intcal",
- "description": "Bad named entity: intcal without a semi-colon",
- "output": [
- [
- "Character",
- "&intcal"
- ]
- ]
- },
- {
- "input": "⊺",
- "description": "Named entity: intcal; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ba"
- ]
- ]
- },
- {
- "input": "&integers",
- "description": "Bad named entity: integers without a semi-colon",
- "output": [
- [
- "Character",
- "&integers"
- ]
- ]
- },
- {
- "input": "ℤ",
- "description": "Named entity: integers; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2124"
- ]
- ]
- },
- {
- "input": "&intercal",
- "description": "Bad named entity: intercal without a semi-colon",
- "output": [
- [
- "Character",
- "&intercal"
- ]
- ]
- },
- {
- "input": "⊺",
- "description": "Named entity: intercal; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ba"
- ]
- ]
- },
- {
- "input": "&intlarhk",
- "description": "Bad named entity: intlarhk without a semi-colon",
- "output": [
- [
- "Character",
- "&intlarhk"
- ]
- ]
- },
- {
- "input": "⨗",
- "description": "Named entity: intlarhk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a17"
- ]
- ]
- },
- {
- "input": "&intprod",
- "description": "Bad named entity: intprod without a semi-colon",
- "output": [
- [
- "Character",
- "&intprod"
- ]
- ]
- },
- {
- "input": "⨼",
- "description": "Named entity: intprod; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a3c"
- ]
- ]
- },
- {
- "input": "&iocy",
- "description": "Bad named entity: iocy without a semi-colon",
- "output": [
- [
- "Character",
- "&iocy"
- ]
- ]
- },
- {
- "input": "ё",
- "description": "Named entity: iocy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0451"
- ]
- ]
- },
- {
- "input": "&iogon",
- "description": "Bad named entity: iogon without a semi-colon",
- "output": [
- [
- "Character",
- "&iogon"
- ]
- ]
- },
- {
- "input": "į",
- "description": "Named entity: iogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u012f"
- ]
- ]
- },
- {
- "input": "&iopf",
- "description": "Bad named entity: iopf without a semi-colon",
- "output": [
- [
- "Character",
- "&iopf"
- ]
- ]
- },
- {
- "input": "𝕚",
- "description": "Named entity: iopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd5a"
- ]
- ]
- },
- {
- "input": "&iota",
- "description": "Bad named entity: iota without a semi-colon",
- "output": [
- [
- "Character",
- "&iota"
- ]
- ]
- },
- {
- "input": "ι",
- "description": "Named entity: iota; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b9"
- ]
- ]
- },
- {
- "input": "&iprod",
- "description": "Bad named entity: iprod without a semi-colon",
- "output": [
- [
- "Character",
- "&iprod"
- ]
- ]
- },
- {
- "input": "⨼",
- "description": "Named entity: iprod; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a3c"
- ]
- ]
- },
- {
- "input": "¿",
- "description": "Named entity: iquest without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00bf"
- ]
- ]
- },
- {
- "input": "¿",
- "description": "Named entity: iquest; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00bf"
- ]
- ]
- },
- {
- "input": "&iscr",
- "description": "Bad named entity: iscr without a semi-colon",
- "output": [
- [
- "Character",
- "&iscr"
- ]
- ]
- },
- {
- "input": "𝒾",
- "description": "Named entity: iscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcbe"
- ]
- ]
- },
- {
- "input": "&isin",
- "description": "Bad named entity: isin without a semi-colon",
- "output": [
- [
- "Character",
- "&isin"
- ]
- ]
- },
- {
- "input": "∈",
- "description": "Named entity: isin; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2208"
- ]
- ]
- },
- {
- "input": "&isinE",
- "description": "Bad named entity: isinE without a semi-colon",
- "output": [
- [
- "Character",
- "&isinE"
- ]
- ]
- },
- {
- "input": "⋹",
- "description": "Named entity: isinE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f9"
- ]
- ]
- },
- {
- "input": "&isindot",
- "description": "Bad named entity: isindot without a semi-colon",
- "output": [
- [
- "Character",
- "&isindot"
- ]
- ]
- },
- {
- "input": "⋵",
- "description": "Named entity: isindot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f5"
- ]
- ]
- },
- {
- "input": "&isins",
- "description": "Bad named entity: isins without a semi-colon",
- "output": [
- [
- "Character",
- "&isins"
- ]
- ]
- },
- {
- "input": "⋴",
- "description": "Named entity: isins; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f4"
- ]
- ]
- },
- {
- "input": "&isinsv",
- "description": "Bad named entity: isinsv without a semi-colon",
- "output": [
- [
- "Character",
- "&isinsv"
- ]
- ]
- },
- {
- "input": "⋳",
- "description": "Named entity: isinsv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f3"
- ]
- ]
- },
- {
- "input": "&isinv",
- "description": "Bad named entity: isinv without a semi-colon",
- "output": [
- [
- "Character",
- "&isinv"
- ]
- ]
- },
- {
- "input": "∈",
- "description": "Named entity: isinv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2208"
- ]
- ]
- },
- {
- "input": "&it",
- "description": "Bad named entity: it without a semi-colon",
- "output": [
- [
- "Character",
- "&it"
- ]
- ]
- },
- {
- "input": "⁢",
- "description": "Named entity: it; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2062"
- ]
- ]
- },
- {
- "input": "&itilde",
- "description": "Bad named entity: itilde without a semi-colon",
- "output": [
- [
- "Character",
- "&itilde"
- ]
- ]
- },
- {
- "input": "ĩ",
- "description": "Named entity: itilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0129"
- ]
- ]
- },
- {
- "input": "&iukcy",
- "description": "Bad named entity: iukcy without a semi-colon",
- "output": [
- [
- "Character",
- "&iukcy"
- ]
- ]
- },
- {
- "input": "і",
- "description": "Named entity: iukcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0456"
- ]
- ]
- },
- {
- "input": "ï",
- "description": "Named entity: iuml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ef"
- ]
- ]
- },
- {
- "input": "ï",
- "description": "Named entity: iuml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ef"
- ]
- ]
- },
- {
- "input": "&jcirc",
- "description": "Bad named entity: jcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&jcirc"
- ]
- ]
- },
- {
- "input": "ĵ",
- "description": "Named entity: jcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0135"
- ]
- ]
- },
- {
- "input": "&jcy",
- "description": "Bad named entity: jcy without a semi-colon",
- "output": [
- [
- "Character",
- "&jcy"
- ]
- ]
- },
- {
- "input": "й",
- "description": "Named entity: jcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0439"
- ]
- ]
- },
- {
- "input": "&jfr",
- "description": "Bad named entity: jfr without a semi-colon",
- "output": [
- [
- "Character",
- "&jfr"
- ]
- ]
- },
- {
- "input": "𝔧",
- "description": "Named entity: jfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd27"
- ]
- ]
- },
- {
- "input": "&jmath",
- "description": "Bad named entity: jmath without a semi-colon",
- "output": [
- [
- "Character",
- "&jmath"
- ]
- ]
- },
- {
- "input": "ȷ",
- "description": "Named entity: jmath; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0237"
- ]
- ]
- },
- {
- "input": "&jopf",
- "description": "Bad named entity: jopf without a semi-colon",
- "output": [
- [
- "Character",
- "&jopf"
- ]
- ]
- },
- {
- "input": "𝕛",
- "description": "Named entity: jopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd5b"
- ]
- ]
- },
- {
- "input": "&jscr",
- "description": "Bad named entity: jscr without a semi-colon",
- "output": [
- [
- "Character",
- "&jscr"
- ]
- ]
- },
- {
- "input": "𝒿",
- "description": "Named entity: jscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcbf"
- ]
- ]
- },
- {
- "input": "&jsercy",
- "description": "Bad named entity: jsercy without a semi-colon",
- "output": [
- [
- "Character",
- "&jsercy"
- ]
- ]
- },
- {
- "input": "ј",
- "description": "Named entity: jsercy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0458"
- ]
- ]
- },
- {
- "input": "&jukcy",
- "description": "Bad named entity: jukcy without a semi-colon",
- "output": [
- [
- "Character",
- "&jukcy"
- ]
- ]
- },
- {
- "input": "є",
- "description": "Named entity: jukcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0454"
- ]
- ]
- },
- {
- "input": "&kappa",
- "description": "Bad named entity: kappa without a semi-colon",
- "output": [
- [
- "Character",
- "&kappa"
- ]
- ]
- },
- {
- "input": "κ",
- "description": "Named entity: kappa; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03ba"
- ]
- ]
- },
- {
- "input": "&kappav",
- "description": "Bad named entity: kappav without a semi-colon",
- "output": [
- [
- "Character",
- "&kappav"
- ]
- ]
- },
- {
- "input": "ϰ",
- "description": "Named entity: kappav; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f0"
- ]
- ]
- },
- {
- "input": "&kcedil",
- "description": "Bad named entity: kcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&kcedil"
- ]
- ]
- },
- {
- "input": "ķ",
- "description": "Named entity: kcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0137"
- ]
- ]
- },
- {
- "input": "&kcy",
- "description": "Bad named entity: kcy without a semi-colon",
- "output": [
- [
- "Character",
- "&kcy"
- ]
- ]
- },
- {
- "input": "к",
- "description": "Named entity: kcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u043a"
- ]
- ]
- },
- {
- "input": "&kfr",
- "description": "Bad named entity: kfr without a semi-colon",
- "output": [
- [
- "Character",
- "&kfr"
- ]
- ]
- },
- {
- "input": "𝔨",
- "description": "Named entity: kfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd28"
- ]
- ]
- },
- {
- "input": "&kgreen",
- "description": "Bad named entity: kgreen without a semi-colon",
- "output": [
- [
- "Character",
- "&kgreen"
- ]
- ]
- },
- {
- "input": "ĸ",
- "description": "Named entity: kgreen; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0138"
- ]
- ]
- },
- {
- "input": "&khcy",
- "description": "Bad named entity: khcy without a semi-colon",
- "output": [
- [
- "Character",
- "&khcy"
- ]
- ]
- },
- {
- "input": "х",
- "description": "Named entity: khcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0445"
- ]
- ]
- },
- {
- "input": "&kjcy",
- "description": "Bad named entity: kjcy without a semi-colon",
- "output": [
- [
- "Character",
- "&kjcy"
- ]
- ]
- },
- {
- "input": "ќ",
- "description": "Named entity: kjcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u045c"
- ]
- ]
- },
- {
- "input": "&kopf",
- "description": "Bad named entity: kopf without a semi-colon",
- "output": [
- [
- "Character",
- "&kopf"
- ]
- ]
- },
- {
- "input": "𝕜",
- "description": "Named entity: kopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd5c"
- ]
- ]
- },
- {
- "input": "&kscr",
- "description": "Bad named entity: kscr without a semi-colon",
- "output": [
- [
- "Character",
- "&kscr"
- ]
- ]
- },
- {
- "input": "𝓀",
- "description": "Named entity: kscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc0"
- ]
- ]
- },
- {
- "input": "&lAarr",
- "description": "Bad named entity: lAarr without a semi-colon",
- "output": [
- [
- "Character",
- "&lAarr"
- ]
- ]
- },
- {
- "input": "⇚",
- "description": "Named entity: lAarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21da"
- ]
- ]
- },
- {
- "input": "&lArr",
- "description": "Bad named entity: lArr without a semi-colon",
- "output": [
- [
- "Character",
- "&lArr"
- ]
- ]
- },
- {
- "input": "⇐",
- "description": "Named entity: lArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d0"
- ]
- ]
- },
- {
- "input": "&lAtail",
- "description": "Bad named entity: lAtail without a semi-colon",
- "output": [
- [
- "Character",
- "&lAtail"
- ]
- ]
- },
- {
- "input": "⤛",
- "description": "Named entity: lAtail; with a semi-colon",
- "output": [
- [
- "Character",
- "\u291b"
- ]
- ]
- },
- {
- "input": "&lBarr",
- "description": "Bad named entity: lBarr without a semi-colon",
- "output": [
- [
- "Character",
- "&lBarr"
- ]
- ]
- },
- {
- "input": "⤎",
- "description": "Named entity: lBarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u290e"
- ]
- ]
- },
- {
- "input": "&lE",
- "description": "Bad named entity: lE without a semi-colon",
- "output": [
- [
- "Character",
- "&lE"
- ]
- ]
- },
- {
- "input": "≦",
- "description": "Named entity: lE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2266"
- ]
- ]
- },
- {
- "input": "&lEg",
- "description": "Bad named entity: lEg without a semi-colon",
- "output": [
- [
- "Character",
- "&lEg"
- ]
- ]
- },
- {
- "input": "⪋",
- "description": "Named entity: lEg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8b"
- ]
- ]
- },
- {
- "input": "&lHar",
- "description": "Bad named entity: lHar without a semi-colon",
- "output": [
- [
- "Character",
- "&lHar"
- ]
- ]
- },
- {
- "input": "⥢",
- "description": "Named entity: lHar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2962"
- ]
- ]
- },
- {
- "input": "&lacute",
- "description": "Bad named entity: lacute without a semi-colon",
- "output": [
- [
- "Character",
- "&lacute"
- ]
- ]
- },
- {
- "input": "ĺ",
- "description": "Named entity: lacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u013a"
- ]
- ]
- },
- {
- "input": "&laemptyv",
- "description": "Bad named entity: laemptyv without a semi-colon",
- "output": [
- [
- "Character",
- "&laemptyv"
- ]
- ]
- },
- {
- "input": "⦴",
- "description": "Named entity: laemptyv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b4"
- ]
- ]
- },
- {
- "input": "&lagran",
- "description": "Bad named entity: lagran without a semi-colon",
- "output": [
- [
- "Character",
- "&lagran"
- ]
- ]
- },
- {
- "input": "ℒ",
- "description": "Named entity: lagran; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2112"
- ]
- ]
- },
- {
- "input": "&lambda",
- "description": "Bad named entity: lambda without a semi-colon",
- "output": [
- [
- "Character",
- "&lambda"
- ]
- ]
- },
- {
- "input": "λ",
- "description": "Named entity: lambda; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03bb"
- ]
- ]
- },
- {
- "input": "&lang",
- "description": "Bad named entity: lang without a semi-colon",
- "output": [
- [
- "Character",
- "&lang"
- ]
- ]
- },
- {
- "input": "〈",
- "description": "Named entity: lang; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e8"
- ]
- ]
- },
- {
- "input": "&langd",
- "description": "Bad named entity: langd without a semi-colon",
- "output": [
- [
- "Character",
- "&langd"
- ]
- ]
- },
- {
- "input": "⦑",
- "description": "Named entity: langd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2991"
- ]
- ]
- },
- {
- "input": "&langle",
- "description": "Bad named entity: langle without a semi-colon",
- "output": [
- [
- "Character",
- "&langle"
- ]
- ]
- },
- {
- "input": "⟨",
- "description": "Named entity: langle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e8"
- ]
- ]
- },
- {
- "input": "&lap",
- "description": "Bad named entity: lap without a semi-colon",
- "output": [
- [
- "Character",
- "&lap"
- ]
- ]
- },
- {
- "input": "⪅",
- "description": "Named entity: lap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a85"
- ]
- ]
- },
- {
- "input": "«",
- "description": "Named entity: laquo without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ab"
- ]
- ]
- },
- {
- "input": "«",
- "description": "Named entity: laquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ab"
- ]
- ]
- },
- {
- "input": "&larr",
- "description": "Bad named entity: larr without a semi-colon",
- "output": [
- [
- "Character",
- "&larr"
- ]
- ]
- },
- {
- "input": "←",
- "description": "Named entity: larr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2190"
- ]
- ]
- },
- {
- "input": "&larrb",
- "description": "Bad named entity: larrb without a semi-colon",
- "output": [
- [
- "Character",
- "&larrb"
- ]
- ]
- },
- {
- "input": "⇤",
- "description": "Named entity: larrb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21e4"
- ]
- ]
- },
- {
- "input": "&larrbfs",
- "description": "Bad named entity: larrbfs without a semi-colon",
- "output": [
- [
- "Character",
- "&larrbfs"
- ]
- ]
- },
- {
- "input": "⤟",
- "description": "Named entity: larrbfs; with a semi-colon",
- "output": [
- [
- "Character",
- "\u291f"
- ]
- ]
- },
- {
- "input": "&larrfs",
- "description": "Bad named entity: larrfs without a semi-colon",
- "output": [
- [
- "Character",
- "&larrfs"
- ]
- ]
- },
- {
- "input": "⤝",
- "description": "Named entity: larrfs; with a semi-colon",
- "output": [
- [
- "Character",
- "\u291d"
- ]
- ]
- },
- {
- "input": "&larrhk",
- "description": "Bad named entity: larrhk without a semi-colon",
- "output": [
- [
- "Character",
- "&larrhk"
- ]
- ]
- },
- {
- "input": "↩",
- "description": "Named entity: larrhk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a9"
- ]
- ]
- },
- {
- "input": "&larrlp",
- "description": "Bad named entity: larrlp without a semi-colon",
- "output": [
- [
- "Character",
- "&larrlp"
- ]
- ]
- },
- {
- "input": "↫",
- "description": "Named entity: larrlp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ab"
- ]
- ]
- },
- {
- "input": "&larrpl",
- "description": "Bad named entity: larrpl without a semi-colon",
- "output": [
- [
- "Character",
- "&larrpl"
- ]
- ]
- },
- {
- "input": "⤹",
- "description": "Named entity: larrpl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2939"
- ]
- ]
- },
- {
- "input": "&larrsim",
- "description": "Bad named entity: larrsim without a semi-colon",
- "output": [
- [
- "Character",
- "&larrsim"
- ]
- ]
- },
- {
- "input": "⥳",
- "description": "Named entity: larrsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2973"
- ]
- ]
- },
- {
- "input": "&larrtl",
- "description": "Bad named entity: larrtl without a semi-colon",
- "output": [
- [
- "Character",
- "&larrtl"
- ]
- ]
- },
- {
- "input": "↢",
- "description": "Named entity: larrtl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a2"
- ]
- ]
- },
- {
- "input": "&lat",
- "description": "Bad named entity: lat without a semi-colon",
- "output": [
- [
- "Character",
- "&lat"
- ]
- ]
- },
- {
- "input": "⪫",
- "description": "Named entity: lat; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aab"
- ]
- ]
- },
- {
- "input": "&latail",
- "description": "Bad named entity: latail without a semi-colon",
- "output": [
- [
- "Character",
- "&latail"
- ]
- ]
- },
- {
- "input": "⤙",
- "description": "Named entity: latail; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2919"
- ]
- ]
- },
- {
- "input": "&late",
- "description": "Bad named entity: late without a semi-colon",
- "output": [
- [
- "Character",
- "&late"
- ]
- ]
- },
- {
- "input": "⪭",
- "description": "Named entity: late; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aad"
- ]
- ]
- },
- {
- "input": "&lates",
- "description": "Bad named entity: lates without a semi-colon",
- "output": [
- [
- "Character",
- "&lates"
- ]
- ]
- },
- {
- "input": "⪭︀",
- "description": "Named entity: lates; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aad\ufe00"
- ]
- ]
- },
- {
- "input": "&lbarr",
- "description": "Bad named entity: lbarr without a semi-colon",
- "output": [
- [
- "Character",
- "&lbarr"
- ]
- ]
- },
- {
- "input": "⤌",
- "description": "Named entity: lbarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u290c"
- ]
- ]
- },
- {
- "input": "&lbbrk",
- "description": "Bad named entity: lbbrk without a semi-colon",
- "output": [
- [
- "Character",
- "&lbbrk"
- ]
- ]
- },
- {
- "input": "❲",
- "description": "Named entity: lbbrk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2772"
- ]
- ]
- },
- {
- "input": "&lbrace",
- "description": "Bad named entity: lbrace without a semi-colon",
- "output": [
- [
- "Character",
- "&lbrace"
- ]
- ]
- },
- {
- "input": "{",
- "description": "Named entity: lbrace; with a semi-colon",
- "output": [
- [
- "Character",
- "{"
- ]
- ]
- },
- {
- "input": "&lbrack",
- "description": "Bad named entity: lbrack without a semi-colon",
- "output": [
- [
- "Character",
- "&lbrack"
- ]
- ]
- },
- {
- "input": "[",
- "description": "Named entity: lbrack; with a semi-colon",
- "output": [
- [
- "Character",
- "["
- ]
- ]
- },
- {
- "input": "&lbrke",
- "description": "Bad named entity: lbrke without a semi-colon",
- "output": [
- [
- "Character",
- "&lbrke"
- ]
- ]
- },
- {
- "input": "⦋",
- "description": "Named entity: lbrke; with a semi-colon",
- "output": [
- [
- "Character",
- "\u298b"
- ]
- ]
- },
- {
- "input": "&lbrksld",
- "description": "Bad named entity: lbrksld without a semi-colon",
- "output": [
- [
- "Character",
- "&lbrksld"
- ]
- ]
- },
- {
- "input": "⦏",
- "description": "Named entity: lbrksld; with a semi-colon",
- "output": [
- [
- "Character",
- "\u298f"
- ]
- ]
- },
- {
- "input": "&lbrkslu",
- "description": "Bad named entity: lbrkslu without a semi-colon",
- "output": [
- [
- "Character",
- "&lbrkslu"
- ]
- ]
- },
- {
- "input": "⦍",
- "description": "Named entity: lbrkslu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u298d"
- ]
- ]
- },
- {
- "input": "&lcaron",
- "description": "Bad named entity: lcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&lcaron"
- ]
- ]
- },
- {
- "input": "ľ",
- "description": "Named entity: lcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u013e"
- ]
- ]
- },
- {
- "input": "&lcedil",
- "description": "Bad named entity: lcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&lcedil"
- ]
- ]
- },
- {
- "input": "ļ",
- "description": "Named entity: lcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u013c"
- ]
- ]
- },
- {
- "input": "&lceil",
- "description": "Bad named entity: lceil without a semi-colon",
- "output": [
- [
- "Character",
- "&lceil"
- ]
- ]
- },
- {
- "input": "⌈",
- "description": "Named entity: lceil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2308"
- ]
- ]
- },
- {
- "input": "&lcub",
- "description": "Bad named entity: lcub without a semi-colon",
- "output": [
- [
- "Character",
- "&lcub"
- ]
- ]
- },
- {
- "input": "{",
- "description": "Named entity: lcub; with a semi-colon",
- "output": [
- [
- "Character",
- "{"
- ]
- ]
- },
- {
- "input": "&lcy",
- "description": "Bad named entity: lcy without a semi-colon",
- "output": [
- [
- "Character",
- "&lcy"
- ]
- ]
- },
- {
- "input": "л",
- "description": "Named entity: lcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u043b"
- ]
- ]
- },
- {
- "input": "&ldca",
- "description": "Bad named entity: ldca without a semi-colon",
- "output": [
- [
- "Character",
- "&ldca"
- ]
- ]
- },
- {
- "input": "⤶",
- "description": "Named entity: ldca; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2936"
- ]
- ]
- },
- {
- "input": "&ldquo",
- "description": "Bad named entity: ldquo without a semi-colon",
- "output": [
- [
- "Character",
- "&ldquo"
- ]
- ]
- },
- {
- "input": "“",
- "description": "Named entity: ldquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201c"
- ]
- ]
- },
- {
- "input": "&ldquor",
- "description": "Bad named entity: ldquor without a semi-colon",
- "output": [
- [
- "Character",
- "&ldquor"
- ]
- ]
- },
- {
- "input": "„",
- "description": "Named entity: ldquor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201e"
- ]
- ]
- },
- {
- "input": "&ldrdhar",
- "description": "Bad named entity: ldrdhar without a semi-colon",
- "output": [
- [
- "Character",
- "&ldrdhar"
- ]
- ]
- },
- {
- "input": "⥧",
- "description": "Named entity: ldrdhar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2967"
- ]
- ]
- },
- {
- "input": "&ldrushar",
- "description": "Bad named entity: ldrushar without a semi-colon",
- "output": [
- [
- "Character",
- "&ldrushar"
- ]
- ]
- },
- {
- "input": "⥋",
- "description": "Named entity: ldrushar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u294b"
- ]
- ]
- },
- {
- "input": "&ldsh",
- "description": "Bad named entity: ldsh without a semi-colon",
- "output": [
- [
- "Character",
- "&ldsh"
- ]
- ]
- },
- {
- "input": "↲",
- "description": "Named entity: ldsh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b2"
- ]
- ]
- },
- {
- "input": "&le",
- "description": "Bad named entity: le without a semi-colon",
- "output": [
- [
- "Character",
- "&le"
- ]
- ]
- },
- {
- "input": "≤",
- "description": "Named entity: le; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2264"
- ]
- ]
- },
- {
- "input": "&leftarrow",
- "description": "Bad named entity: leftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&leftarrow"
- ]
- ]
- },
- {
- "input": "←",
- "description": "Named entity: leftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2190"
- ]
- ]
- },
- {
- "input": "&leftarrowtail",
- "description": "Bad named entity: leftarrowtail without a semi-colon",
- "output": [
- [
- "Character",
- "&leftarrowtail"
- ]
- ]
- },
- {
- "input": "↢",
- "description": "Named entity: leftarrowtail; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a2"
- ]
- ]
- },
- {
- "input": "&leftharpoondown",
- "description": "Bad named entity: leftharpoondown without a semi-colon",
- "output": [
- [
- "Character",
- "&leftharpoondown"
- ]
- ]
- },
- {
- "input": "↽",
- "description": "Named entity: leftharpoondown; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bd"
- ]
- ]
- },
- {
- "input": "&leftharpoonup",
- "description": "Bad named entity: leftharpoonup without a semi-colon",
- "output": [
- [
- "Character",
- "&leftharpoonup"
- ]
- ]
- },
- {
- "input": "↼",
- "description": "Named entity: leftharpoonup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bc"
- ]
- ]
- },
- {
- "input": "&leftleftarrows",
- "description": "Bad named entity: leftleftarrows without a semi-colon",
- "output": [
- [
- "Character",
- "&leftleftarrows"
- ]
- ]
- },
- {
- "input": "⇇",
- "description": "Named entity: leftleftarrows; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c7"
- ]
- ]
- },
- {
- "input": "&leftrightarrow",
- "description": "Bad named entity: leftrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&leftrightarrow"
- ]
- ]
- },
- {
- "input": "↔",
- "description": "Named entity: leftrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2194"
- ]
- ]
- },
- {
- "input": "&leftrightarrows",
- "description": "Bad named entity: leftrightarrows without a semi-colon",
- "output": [
- [
- "Character",
- "&leftrightarrows"
- ]
- ]
- },
- {
- "input": "⇆",
- "description": "Named entity: leftrightarrows; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c6"
- ]
- ]
- },
- {
- "input": "&leftrightharpoons",
- "description": "Bad named entity: leftrightharpoons without a semi-colon",
- "output": [
- [
- "Character",
- "&leftrightharpoons"
- ]
- ]
- },
- {
- "input": "⇋",
- "description": "Named entity: leftrightharpoons; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cb"
- ]
- ]
- },
- {
- "input": "&leftrightsquigarrow",
- "description": "Bad named entity: leftrightsquigarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&leftrightsquigarrow"
- ]
- ]
- },
- {
- "input": "↭",
- "description": "Named entity: leftrightsquigarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ad"
- ]
- ]
- },
- {
- "input": "&leftthreetimes",
- "description": "Bad named entity: leftthreetimes without a semi-colon",
- "output": [
- [
- "Character",
- "&leftthreetimes"
- ]
- ]
- },
- {
- "input": "⋋",
- "description": "Named entity: leftthreetimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22cb"
- ]
- ]
- },
- {
- "input": "&leg",
- "description": "Bad named entity: leg without a semi-colon",
- "output": [
- [
- "Character",
- "&leg"
- ]
- ]
- },
- {
- "input": "⋚",
- "description": "Named entity: leg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22da"
- ]
- ]
- },
- {
- "input": "&leq",
- "description": "Bad named entity: leq without a semi-colon",
- "output": [
- [
- "Character",
- "&leq"
- ]
- ]
- },
- {
- "input": "≤",
- "description": "Named entity: leq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2264"
- ]
- ]
- },
- {
- "input": "&leqq",
- "description": "Bad named entity: leqq without a semi-colon",
- "output": [
- [
- "Character",
- "&leqq"
- ]
- ]
- },
- {
- "input": "≦",
- "description": "Named entity: leqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2266"
- ]
- ]
- },
- {
- "input": "&leqslant",
- "description": "Bad named entity: leqslant without a semi-colon",
- "output": [
- [
- "Character",
- "&leqslant"
- ]
- ]
- },
- {
- "input": "⩽",
- "description": "Named entity: leqslant; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7d"
- ]
- ]
- },
- {
- "input": "&les",
- "description": "Bad named entity: les without a semi-colon",
- "output": [
- [
- "Character",
- "&les"
- ]
- ]
- },
- {
- "input": "⩽",
- "description": "Named entity: les; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7d"
- ]
- ]
- },
- {
- "input": "&lescc",
- "description": "Bad named entity: lescc without a semi-colon",
- "output": [
- [
- "Character",
- "&lescc"
- ]
- ]
- },
- {
- "input": "⪨",
- "description": "Named entity: lescc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa8"
- ]
- ]
- },
- {
- "input": "&lesdot",
- "description": "Bad named entity: lesdot without a semi-colon",
- "output": [
- [
- "Character",
- "&lesdot"
- ]
- ]
- },
- {
- "input": "⩿",
- "description": "Named entity: lesdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7f"
- ]
- ]
- },
- {
- "input": "&lesdoto",
- "description": "Bad named entity: lesdoto without a semi-colon",
- "output": [
- [
- "Character",
- "&lesdoto"
- ]
- ]
- },
- {
- "input": "⪁",
- "description": "Named entity: lesdoto; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a81"
- ]
- ]
- },
- {
- "input": "&lesdotor",
- "description": "Bad named entity: lesdotor without a semi-colon",
- "output": [
- [
- "Character",
- "&lesdotor"
- ]
- ]
- },
- {
- "input": "⪃",
- "description": "Named entity: lesdotor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a83"
- ]
- ]
- },
- {
- "input": "&lesg",
- "description": "Bad named entity: lesg without a semi-colon",
- "output": [
- [
- "Character",
- "&lesg"
- ]
- ]
- },
- {
- "input": "⋚︀",
- "description": "Named entity: lesg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22da\ufe00"
- ]
- ]
- },
- {
- "input": "&lesges",
- "description": "Bad named entity: lesges without a semi-colon",
- "output": [
- [
- "Character",
- "&lesges"
- ]
- ]
- },
- {
- "input": "⪓",
- "description": "Named entity: lesges; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a93"
- ]
- ]
- },
- {
- "input": "&lessapprox",
- "description": "Bad named entity: lessapprox without a semi-colon",
- "output": [
- [
- "Character",
- "&lessapprox"
- ]
- ]
- },
- {
- "input": "⪅",
- "description": "Named entity: lessapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a85"
- ]
- ]
- },
- {
- "input": "&lessdot",
- "description": "Bad named entity: lessdot without a semi-colon",
- "output": [
- [
- "Character",
- "&lessdot"
- ]
- ]
- },
- {
- "input": "⋖",
- "description": "Named entity: lessdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d6"
- ]
- ]
- },
- {
- "input": "&lesseqgtr",
- "description": "Bad named entity: lesseqgtr without a semi-colon",
- "output": [
- [
- "Character",
- "&lesseqgtr"
- ]
- ]
- },
- {
- "input": "⋚",
- "description": "Named entity: lesseqgtr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22da"
- ]
- ]
- },
- {
- "input": "&lesseqqgtr",
- "description": "Bad named entity: lesseqqgtr without a semi-colon",
- "output": [
- [
- "Character",
- "&lesseqqgtr"
- ]
- ]
- },
- {
- "input": "⪋",
- "description": "Named entity: lesseqqgtr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8b"
- ]
- ]
- },
- {
- "input": "&lessgtr",
- "description": "Bad named entity: lessgtr without a semi-colon",
- "output": [
- [
- "Character",
- "&lessgtr"
- ]
- ]
- },
- {
- "input": "≶",
- "description": "Named entity: lessgtr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2276"
- ]
- ]
- },
- {
- "input": "&lesssim",
- "description": "Bad named entity: lesssim without a semi-colon",
- "output": [
- [
- "Character",
- "&lesssim"
- ]
- ]
- },
- {
- "input": "≲",
- "description": "Named entity: lesssim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2272"
- ]
- ]
- },
- {
- "input": "&lfisht",
- "description": "Bad named entity: lfisht without a semi-colon",
- "output": [
- [
- "Character",
- "&lfisht"
- ]
- ]
- },
- {
- "input": "⥼",
- "description": "Named entity: lfisht; with a semi-colon",
- "output": [
- [
- "Character",
- "\u297c"
- ]
- ]
- },
- {
- "input": "&lfloor",
- "description": "Bad named entity: lfloor without a semi-colon",
- "output": [
- [
- "Character",
- "&lfloor"
- ]
- ]
- },
- {
- "input": "⌊",
- "description": "Named entity: lfloor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u230a"
- ]
- ]
- },
- {
- "input": "&lfr",
- "description": "Bad named entity: lfr without a semi-colon",
- "output": [
- [
- "Character",
- "&lfr"
- ]
- ]
- },
- {
- "input": "𝔩",
- "description": "Named entity: lfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd29"
- ]
- ]
- },
- {
- "input": "&lg",
- "description": "Bad named entity: lg without a semi-colon",
- "output": [
- [
- "Character",
- "&lg"
- ]
- ]
- },
- {
- "input": "≶",
- "description": "Named entity: lg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2276"
- ]
- ]
- },
- {
- "input": "&lgE",
- "description": "Bad named entity: lgE without a semi-colon",
- "output": [
- [
- "Character",
- "&lgE"
- ]
- ]
- },
- {
- "input": "⪑",
- "description": "Named entity: lgE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a91"
- ]
- ]
- },
- {
- "input": "&lhard",
- "description": "Bad named entity: lhard without a semi-colon",
- "output": [
- [
- "Character",
- "&lhard"
- ]
- ]
- },
- {
- "input": "↽",
- "description": "Named entity: lhard; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bd"
- ]
- ]
- },
- {
- "input": "&lharu",
- "description": "Bad named entity: lharu without a semi-colon",
- "output": [
- [
- "Character",
- "&lharu"
- ]
- ]
- },
- {
- "input": "↼",
- "description": "Named entity: lharu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bc"
- ]
- ]
- },
- {
- "input": "&lharul",
- "description": "Bad named entity: lharul without a semi-colon",
- "output": [
- [
- "Character",
- "&lharul"
- ]
- ]
- },
- {
- "input": "⥪",
- "description": "Named entity: lharul; with a semi-colon",
- "output": [
- [
- "Character",
- "\u296a"
- ]
- ]
- },
- {
- "input": "&lhblk",
- "description": "Bad named entity: lhblk without a semi-colon",
- "output": [
- [
- "Character",
- "&lhblk"
- ]
- ]
- },
- {
- "input": "▄",
- "description": "Named entity: lhblk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2584"
- ]
- ]
- },
- {
- "input": "&ljcy",
- "description": "Bad named entity: ljcy without a semi-colon",
- "output": [
- [
- "Character",
- "&ljcy"
- ]
- ]
- },
- {
- "input": "љ",
- "description": "Named entity: ljcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0459"
- ]
- ]
- },
- {
- "input": "&ll",
- "description": "Bad named entity: ll without a semi-colon",
- "output": [
- [
- "Character",
- "&ll"
- ]
- ]
- },
- {
- "input": "≪",
- "description": "Named entity: ll; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226a"
- ]
- ]
- },
- {
- "input": "&llarr",
- "description": "Bad named entity: llarr without a semi-colon",
- "output": [
- [
- "Character",
- "&llarr"
- ]
- ]
- },
- {
- "input": "⇇",
- "description": "Named entity: llarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c7"
- ]
- ]
- },
- {
- "input": "&llcorner",
- "description": "Bad named entity: llcorner without a semi-colon",
- "output": [
- [
- "Character",
- "&llcorner"
- ]
- ]
- },
- {
- "input": "⌞",
- "description": "Named entity: llcorner; with a semi-colon",
- "output": [
- [
- "Character",
- "\u231e"
- ]
- ]
- },
- {
- "input": "&llhard",
- "description": "Bad named entity: llhard without a semi-colon",
- "output": [
- [
- "Character",
- "&llhard"
- ]
- ]
- },
- {
- "input": "⥫",
- "description": "Named entity: llhard; with a semi-colon",
- "output": [
- [
- "Character",
- "\u296b"
- ]
- ]
- },
- {
- "input": "&lltri",
- "description": "Bad named entity: lltri without a semi-colon",
- "output": [
- [
- "Character",
- "&lltri"
- ]
- ]
- },
- {
- "input": "◺",
- "description": "Named entity: lltri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25fa"
- ]
- ]
- },
- {
- "input": "&lmidot",
- "description": "Bad named entity: lmidot without a semi-colon",
- "output": [
- [
- "Character",
- "&lmidot"
- ]
- ]
- },
- {
- "input": "ŀ",
- "description": "Named entity: lmidot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0140"
- ]
- ]
- },
- {
- "input": "&lmoust",
- "description": "Bad named entity: lmoust without a semi-colon",
- "output": [
- [
- "Character",
- "&lmoust"
- ]
- ]
- },
- {
- "input": "⎰",
- "description": "Named entity: lmoust; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b0"
- ]
- ]
- },
- {
- "input": "&lmoustache",
- "description": "Bad named entity: lmoustache without a semi-colon",
- "output": [
- [
- "Character",
- "&lmoustache"
- ]
- ]
- },
- {
- "input": "⎰",
- "description": "Named entity: lmoustache; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b0"
- ]
- ]
- },
- {
- "input": "&lnE",
- "description": "Bad named entity: lnE without a semi-colon",
- "output": [
- [
- "Character",
- "&lnE"
- ]
- ]
- },
- {
- "input": "≨",
- "description": "Named entity: lnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2268"
- ]
- ]
- },
- {
- "input": "&lnap",
- "description": "Bad named entity: lnap without a semi-colon",
- "output": [
- [
- "Character",
- "&lnap"
- ]
- ]
- },
- {
- "input": "⪉",
- "description": "Named entity: lnap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a89"
- ]
- ]
- },
- {
- "input": "&lnapprox",
- "description": "Bad named entity: lnapprox without a semi-colon",
- "output": [
- [
- "Character",
- "&lnapprox"
- ]
- ]
- },
- {
- "input": "⪉",
- "description": "Named entity: lnapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a89"
- ]
- ]
- },
- {
- "input": "&lne",
- "description": "Bad named entity: lne without a semi-colon",
- "output": [
- [
- "Character",
- "&lne"
- ]
- ]
- },
- {
- "input": "⪇",
- "description": "Named entity: lne; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a87"
- ]
- ]
- },
- {
- "input": "&lneq",
- "description": "Bad named entity: lneq without a semi-colon",
- "output": [
- [
- "Character",
- "&lneq"
- ]
- ]
- },
- {
- "input": "⪇",
- "description": "Named entity: lneq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a87"
- ]
- ]
- },
- {
- "input": "&lneqq",
- "description": "Bad named entity: lneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&lneqq"
- ]
- ]
- },
- {
- "input": "≨",
- "description": "Named entity: lneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2268"
- ]
- ]
- },
- {
- "input": "&lnsim",
- "description": "Bad named entity: lnsim without a semi-colon",
- "output": [
- [
- "Character",
- "&lnsim"
- ]
- ]
- },
- {
- "input": "⋦",
- "description": "Named entity: lnsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e6"
- ]
- ]
- },
- {
- "input": "&loang",
- "description": "Bad named entity: loang without a semi-colon",
- "output": [
- [
- "Character",
- "&loang"
- ]
- ]
- },
- {
- "input": "⟬",
- "description": "Named entity: loang; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27ec"
- ]
- ]
- },
- {
- "input": "&loarr",
- "description": "Bad named entity: loarr without a semi-colon",
- "output": [
- [
- "Character",
- "&loarr"
- ]
- ]
- },
- {
- "input": "⇽",
- "description": "Named entity: loarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21fd"
- ]
- ]
- },
- {
- "input": "&lobrk",
- "description": "Bad named entity: lobrk without a semi-colon",
- "output": [
- [
- "Character",
- "&lobrk"
- ]
- ]
- },
- {
- "input": "⟦",
- "description": "Named entity: lobrk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e6"
- ]
- ]
- },
- {
- "input": "&longleftarrow",
- "description": "Bad named entity: longleftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&longleftarrow"
- ]
- ]
- },
- {
- "input": "⟵",
- "description": "Named entity: longleftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f5"
- ]
- ]
- },
- {
- "input": "&longleftrightarrow",
- "description": "Bad named entity: longleftrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&longleftrightarrow"
- ]
- ]
- },
- {
- "input": "⟷",
- "description": "Named entity: longleftrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f7"
- ]
- ]
- },
- {
- "input": "&longmapsto",
- "description": "Bad named entity: longmapsto without a semi-colon",
- "output": [
- [
- "Character",
- "&longmapsto"
- ]
- ]
- },
- {
- "input": "⟼",
- "description": "Named entity: longmapsto; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27fc"
- ]
- ]
- },
- {
- "input": "&longrightarrow",
- "description": "Bad named entity: longrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&longrightarrow"
- ]
- ]
- },
- {
- "input": "⟶",
- "description": "Named entity: longrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f6"
- ]
- ]
- },
- {
- "input": "&looparrowleft",
- "description": "Bad named entity: looparrowleft without a semi-colon",
- "output": [
- [
- "Character",
- "&looparrowleft"
- ]
- ]
- },
- {
- "input": "↫",
- "description": "Named entity: looparrowleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ab"
- ]
- ]
- },
- {
- "input": "&looparrowright",
- "description": "Bad named entity: looparrowright without a semi-colon",
- "output": [
- [
- "Character",
- "&looparrowright"
- ]
- ]
- },
- {
- "input": "↬",
- "description": "Named entity: looparrowright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ac"
- ]
- ]
- },
- {
- "input": "&lopar",
- "description": "Bad named entity: lopar without a semi-colon",
- "output": [
- [
- "Character",
- "&lopar"
- ]
- ]
- },
- {
- "input": "⦅",
- "description": "Named entity: lopar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2985"
- ]
- ]
- },
- {
- "input": "&lopf",
- "description": "Bad named entity: lopf without a semi-colon",
- "output": [
- [
- "Character",
- "&lopf"
- ]
- ]
- },
- {
- "input": "𝕝",
- "description": "Named entity: lopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd5d"
- ]
- ]
- },
- {
- "input": "&loplus",
- "description": "Bad named entity: loplus without a semi-colon",
- "output": [
- [
- "Character",
- "&loplus"
- ]
- ]
- },
- {
- "input": "⨭",
- "description": "Named entity: loplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a2d"
- ]
- ]
- },
- {
- "input": "&lotimes",
- "description": "Bad named entity: lotimes without a semi-colon",
- "output": [
- [
- "Character",
- "&lotimes"
- ]
- ]
- },
- {
- "input": "⨴",
- "description": "Named entity: lotimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a34"
- ]
- ]
- },
- {
- "input": "&lowast",
- "description": "Bad named entity: lowast without a semi-colon",
- "output": [
- [
- "Character",
- "&lowast"
- ]
- ]
- },
- {
- "input": "∗",
- "description": "Named entity: lowast; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2217"
- ]
- ]
- },
- {
- "input": "&lowbar",
- "description": "Bad named entity: lowbar without a semi-colon",
- "output": [
- [
- "Character",
- "&lowbar"
- ]
- ]
- },
- {
- "input": "_",
- "description": "Named entity: lowbar; with a semi-colon",
- "output": [
- [
- "Character",
- "_"
- ]
- ]
- },
- {
- "input": "&loz",
- "description": "Bad named entity: loz without a semi-colon",
- "output": [
- [
- "Character",
- "&loz"
- ]
- ]
- },
- {
- "input": "◊",
- "description": "Named entity: loz; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25ca"
- ]
- ]
- },
- {
- "input": "&lozenge",
- "description": "Bad named entity: lozenge without a semi-colon",
- "output": [
- [
- "Character",
- "&lozenge"
- ]
- ]
- },
- {
- "input": "◊",
- "description": "Named entity: lozenge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25ca"
- ]
- ]
- },
- {
- "input": "&lozf",
- "description": "Bad named entity: lozf without a semi-colon",
- "output": [
- [
- "Character",
- "&lozf"
- ]
- ]
- },
- {
- "input": "⧫",
- "description": "Named entity: lozf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29eb"
- ]
- ]
- },
- {
- "input": "&lpar",
- "description": "Bad named entity: lpar without a semi-colon",
- "output": [
- [
- "Character",
- "&lpar"
- ]
- ]
- },
- {
- "input": "(",
- "description": "Named entity: lpar; with a semi-colon",
- "output": [
- [
- "Character",
- "("
- ]
- ]
- },
- {
- "input": "&lparlt",
- "description": "Bad named entity: lparlt without a semi-colon",
- "output": [
- [
- "Character",
- "&lparlt"
- ]
- ]
- },
- {
- "input": "⦓",
- "description": "Named entity: lparlt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2993"
- ]
- ]
- },
- {
- "input": "&lrarr",
- "description": "Bad named entity: lrarr without a semi-colon",
- "output": [
- [
- "Character",
- "&lrarr"
- ]
- ]
- },
- {
- "input": "⇆",
- "description": "Named entity: lrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c6"
- ]
- ]
- },
- {
- "input": "&lrcorner",
- "description": "Bad named entity: lrcorner without a semi-colon",
- "output": [
- [
- "Character",
- "&lrcorner"
- ]
- ]
- },
- {
- "input": "⌟",
- "description": "Named entity: lrcorner; with a semi-colon",
- "output": [
- [
- "Character",
- "\u231f"
- ]
- ]
- },
- {
- "input": "&lrhar",
- "description": "Bad named entity: lrhar without a semi-colon",
- "output": [
- [
- "Character",
- "&lrhar"
- ]
- ]
- },
- {
- "input": "⇋",
- "description": "Named entity: lrhar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cb"
- ]
- ]
- },
- {
- "input": "&lrhard",
- "description": "Bad named entity: lrhard without a semi-colon",
- "output": [
- [
- "Character",
- "&lrhard"
- ]
- ]
- },
- {
- "input": "⥭",
- "description": "Named entity: lrhard; with a semi-colon",
- "output": [
- [
- "Character",
- "\u296d"
- ]
- ]
- },
- {
- "input": "&lrm",
- "description": "Bad named entity: lrm without a semi-colon",
- "output": [
- [
- "Character",
- "&lrm"
- ]
- ]
- },
- {
- "input": "",
- "description": "Named entity: lrm; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200e"
- ]
- ]
- },
- {
- "input": "&lrtri",
- "description": "Bad named entity: lrtri without a semi-colon",
- "output": [
- [
- "Character",
- "&lrtri"
- ]
- ]
- },
- {
- "input": "⊿",
- "description": "Named entity: lrtri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22bf"
- ]
- ]
- },
- {
- "input": "&lsaquo",
- "description": "Bad named entity: lsaquo without a semi-colon",
- "output": [
- [
- "Character",
- "&lsaquo"
- ]
- ]
- },
- {
- "input": "‹",
- "description": "Named entity: lsaquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2039"
- ]
- ]
- },
- {
- "input": "&lscr",
- "description": "Bad named entity: lscr without a semi-colon",
- "output": [
- [
- "Character",
- "&lscr"
- ]
- ]
- },
- {
- "input": "𝓁",
- "description": "Named entity: lscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc1"
- ]
- ]
- },
- {
- "input": "&lsh",
- "description": "Bad named entity: lsh without a semi-colon",
- "output": [
- [
- "Character",
- "&lsh"
- ]
- ]
- },
- {
- "input": "↰",
- "description": "Named entity: lsh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b0"
- ]
- ]
- },
- {
- "input": "&lsim",
- "description": "Bad named entity: lsim without a semi-colon",
- "output": [
- [
- "Character",
- "&lsim"
- ]
- ]
- },
- {
- "input": "≲",
- "description": "Named entity: lsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2272"
- ]
- ]
- },
- {
- "input": "&lsime",
- "description": "Bad named entity: lsime without a semi-colon",
- "output": [
- [
- "Character",
- "&lsime"
- ]
- ]
- },
- {
- "input": "⪍",
- "description": "Named entity: lsime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8d"
- ]
- ]
- },
- {
- "input": "&lsimg",
- "description": "Bad named entity: lsimg without a semi-colon",
- "output": [
- [
- "Character",
- "&lsimg"
- ]
- ]
- },
- {
- "input": "⪏",
- "description": "Named entity: lsimg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a8f"
- ]
- ]
- },
- {
- "input": "&lsqb",
- "description": "Bad named entity: lsqb without a semi-colon",
- "output": [
- [
- "Character",
- "&lsqb"
- ]
- ]
- },
- {
- "input": "[",
- "description": "Named entity: lsqb; with a semi-colon",
- "output": [
- [
- "Character",
- "["
- ]
- ]
- },
- {
- "input": "&lsquo",
- "description": "Bad named entity: lsquo without a semi-colon",
- "output": [
- [
- "Character",
- "&lsquo"
- ]
- ]
- },
- {
- "input": "‘",
- "description": "Named entity: lsquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2018"
- ]
- ]
- },
- {
- "input": "&lsquor",
- "description": "Bad named entity: lsquor without a semi-colon",
- "output": [
- [
- "Character",
- "&lsquor"
- ]
- ]
- },
- {
- "input": "‚",
- "description": "Named entity: lsquor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201a"
- ]
- ]
- },
- {
- "input": "&lstrok",
- "description": "Bad named entity: lstrok without a semi-colon",
- "output": [
- [
- "Character",
- "&lstrok"
- ]
- ]
- },
- {
- "input": "ł",
- "description": "Named entity: lstrok; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0142"
- ]
- ]
- },
- {
- "input": "<",
- "description": "Named entity: lt without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "<"
- ]
- ]
- },
- {
- "input": "<",
- "description": "Named entity: lt; with a semi-colon",
- "output": [
- [
- "Character",
- "<"
- ]
- ]
- },
- {
- "input": "⪦",
- "description": "Named entity: ltcc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa6"
- ]
- ]
- },
- {
- "input": "⩹",
- "description": "Named entity: ltcir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a79"
- ]
- ]
- },
- {
- "input": "⋖",
- "description": "Named entity: ltdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d6"
- ]
- ]
- },
- {
- "input": "⋋",
- "description": "Named entity: lthree; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22cb"
- ]
- ]
- },
- {
- "input": "⋉",
- "description": "Named entity: ltimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c9"
- ]
- ]
- },
- {
- "input": "⥶",
- "description": "Named entity: ltlarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2976"
- ]
- ]
- },
- {
- "input": "⩻",
- "description": "Named entity: ltquest; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7b"
- ]
- ]
- },
- {
- "input": "⦖",
- "description": "Named entity: ltrPar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2996"
- ]
- ]
- },
- {
- "input": "◃",
- "description": "Named entity: ltri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25c3"
- ]
- ]
- },
- {
- "input": "⊴",
- "description": "Named entity: ltrie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b4"
- ]
- ]
- },
- {
- "input": "◂",
- "description": "Named entity: ltrif; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25c2"
- ]
- ]
- },
- {
- "input": "&lurdshar",
- "description": "Bad named entity: lurdshar without a semi-colon",
- "output": [
- [
- "Character",
- "&lurdshar"
- ]
- ]
- },
- {
- "input": "⥊",
- "description": "Named entity: lurdshar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u294a"
- ]
- ]
- },
- {
- "input": "&luruhar",
- "description": "Bad named entity: luruhar without a semi-colon",
- "output": [
- [
- "Character",
- "&luruhar"
- ]
- ]
- },
- {
- "input": "⥦",
- "description": "Named entity: luruhar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2966"
- ]
- ]
- },
- {
- "input": "&lvertneqq",
- "description": "Bad named entity: lvertneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&lvertneqq"
- ]
- ]
- },
- {
- "input": "≨︀",
- "description": "Named entity: lvertneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2268\ufe00"
- ]
- ]
- },
- {
- "input": "&lvnE",
- "description": "Bad named entity: lvnE without a semi-colon",
- "output": [
- [
- "Character",
- "&lvnE"
- ]
- ]
- },
- {
- "input": "≨︀",
- "description": "Named entity: lvnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2268\ufe00"
- ]
- ]
- },
- {
- "input": "&mDDot",
- "description": "Bad named entity: mDDot without a semi-colon",
- "output": [
- [
- "Character",
- "&mDDot"
- ]
- ]
- },
- {
- "input": "∺",
- "description": "Named entity: mDDot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223a"
- ]
- ]
- },
- {
- "input": "¯",
- "description": "Named entity: macr without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00af"
- ]
- ]
- },
- {
- "input": "¯",
- "description": "Named entity: macr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00af"
- ]
- ]
- },
- {
- "input": "&male",
- "description": "Bad named entity: male without a semi-colon",
- "output": [
- [
- "Character",
- "&male"
- ]
- ]
- },
- {
- "input": "♂",
- "description": "Named entity: male; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2642"
- ]
- ]
- },
- {
- "input": "&malt",
- "description": "Bad named entity: malt without a semi-colon",
- "output": [
- [
- "Character",
- "&malt"
- ]
- ]
- },
- {
- "input": "✠",
- "description": "Named entity: malt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2720"
- ]
- ]
- },
- {
- "input": "&maltese",
- "description": "Bad named entity: maltese without a semi-colon",
- "output": [
- [
- "Character",
- "&maltese"
- ]
- ]
- },
- {
- "input": "✠",
- "description": "Named entity: maltese; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2720"
- ]
- ]
- },
- {
- "input": "&map",
- "description": "Bad named entity: map without a semi-colon",
- "output": [
- [
- "Character",
- "&map"
- ]
- ]
- },
- {
- "input": "↦",
- "description": "Named entity: map; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a6"
- ]
- ]
- },
- {
- "input": "&mapsto",
- "description": "Bad named entity: mapsto without a semi-colon",
- "output": [
- [
- "Character",
- "&mapsto"
- ]
- ]
- },
- {
- "input": "↦",
- "description": "Named entity: mapsto; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a6"
- ]
- ]
- },
- {
- "input": "&mapstodown",
- "description": "Bad named entity: mapstodown without a semi-colon",
- "output": [
- [
- "Character",
- "&mapstodown"
- ]
- ]
- },
- {
- "input": "↧",
- "description": "Named entity: mapstodown; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a7"
- ]
- ]
- },
- {
- "input": "&mapstoleft",
- "description": "Bad named entity: mapstoleft without a semi-colon",
- "output": [
- [
- "Character",
- "&mapstoleft"
- ]
- ]
- },
- {
- "input": "↤",
- "description": "Named entity: mapstoleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a4"
- ]
- ]
- },
- {
- "input": "&mapstoup",
- "description": "Bad named entity: mapstoup without a semi-colon",
- "output": [
- [
- "Character",
- "&mapstoup"
- ]
- ]
- },
- {
- "input": "↥",
- "description": "Named entity: mapstoup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a5"
- ]
- ]
- },
- {
- "input": "&marker",
- "description": "Bad named entity: marker without a semi-colon",
- "output": [
- [
- "Character",
- "&marker"
- ]
- ]
- },
- {
- "input": "▮",
- "description": "Named entity: marker; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25ae"
- ]
- ]
- },
- {
- "input": "&mcomma",
- "description": "Bad named entity: mcomma without a semi-colon",
- "output": [
- [
- "Character",
- "&mcomma"
- ]
- ]
- },
- {
- "input": "⨩",
- "description": "Named entity: mcomma; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a29"
- ]
- ]
- },
- {
- "input": "&mcy",
- "description": "Bad named entity: mcy without a semi-colon",
- "output": [
- [
- "Character",
- "&mcy"
- ]
- ]
- },
- {
- "input": "м",
- "description": "Named entity: mcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u043c"
- ]
- ]
- },
- {
- "input": "&mdash",
- "description": "Bad named entity: mdash without a semi-colon",
- "output": [
- [
- "Character",
- "&mdash"
- ]
- ]
- },
- {
- "input": "—",
- "description": "Named entity: mdash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2014"
- ]
- ]
- },
- {
- "input": "&measuredangle",
- "description": "Bad named entity: measuredangle without a semi-colon",
- "output": [
- [
- "Character",
- "&measuredangle"
- ]
- ]
- },
- {
- "input": "∡",
- "description": "Named entity: measuredangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2221"
- ]
- ]
- },
- {
- "input": "&mfr",
- "description": "Bad named entity: mfr without a semi-colon",
- "output": [
- [
- "Character",
- "&mfr"
- ]
- ]
- },
- {
- "input": "𝔪",
- "description": "Named entity: mfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd2a"
- ]
- ]
- },
- {
- "input": "&mho",
- "description": "Bad named entity: mho without a semi-colon",
- "output": [
- [
- "Character",
- "&mho"
- ]
- ]
- },
- {
- "input": "℧",
- "description": "Named entity: mho; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2127"
- ]
- ]
- },
- {
- "input": "µ",
- "description": "Named entity: micro without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b5"
- ]
- ]
- },
- {
- "input": "µ",
- "description": "Named entity: micro; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b5"
- ]
- ]
- },
- {
- "input": "&mid",
- "description": "Bad named entity: mid without a semi-colon",
- "output": [
- [
- "Character",
- "&mid"
- ]
- ]
- },
- {
- "input": "∣",
- "description": "Named entity: mid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2223"
- ]
- ]
- },
- {
- "input": "&midast",
- "description": "Bad named entity: midast without a semi-colon",
- "output": [
- [
- "Character",
- "&midast"
- ]
- ]
- },
- {
- "input": "*",
- "description": "Named entity: midast; with a semi-colon",
- "output": [
- [
- "Character",
- "*"
- ]
- ]
- },
- {
- "input": "&midcir",
- "description": "Bad named entity: midcir without a semi-colon",
- "output": [
- [
- "Character",
- "&midcir"
- ]
- ]
- },
- {
- "input": "⫰",
- "description": "Named entity: midcir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2af0"
- ]
- ]
- },
- {
- "input": "·",
- "description": "Named entity: middot without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b7"
- ]
- ]
- },
- {
- "input": "·",
- "description": "Named entity: middot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b7"
- ]
- ]
- },
- {
- "input": "&minus",
- "description": "Bad named entity: minus without a semi-colon",
- "output": [
- [
- "Character",
- "&minus"
- ]
- ]
- },
- {
- "input": "−",
- "description": "Named entity: minus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2212"
- ]
- ]
- },
- {
- "input": "&minusb",
- "description": "Bad named entity: minusb without a semi-colon",
- "output": [
- [
- "Character",
- "&minusb"
- ]
- ]
- },
- {
- "input": "⊟",
- "description": "Named entity: minusb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229f"
- ]
- ]
- },
- {
- "input": "&minusd",
- "description": "Bad named entity: minusd without a semi-colon",
- "output": [
- [
- "Character",
- "&minusd"
- ]
- ]
- },
- {
- "input": "∸",
- "description": "Named entity: minusd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2238"
- ]
- ]
- },
- {
- "input": "&minusdu",
- "description": "Bad named entity: minusdu without a semi-colon",
- "output": [
- [
- "Character",
- "&minusdu"
- ]
- ]
- },
- {
- "input": "⨪",
- "description": "Named entity: minusdu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a2a"
- ]
- ]
- },
- {
- "input": "&mlcp",
- "description": "Bad named entity: mlcp without a semi-colon",
- "output": [
- [
- "Character",
- "&mlcp"
- ]
- ]
- },
- {
- "input": "⫛",
- "description": "Named entity: mlcp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2adb"
- ]
- ]
- },
- {
- "input": "&mldr",
- "description": "Bad named entity: mldr without a semi-colon",
- "output": [
- [
- "Character",
- "&mldr"
- ]
- ]
- },
- {
- "input": "…",
- "description": "Named entity: mldr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2026"
- ]
- ]
- },
- {
- "input": "&mnplus",
- "description": "Bad named entity: mnplus without a semi-colon",
- "output": [
- [
- "Character",
- "&mnplus"
- ]
- ]
- },
- {
- "input": "∓",
- "description": "Named entity: mnplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2213"
- ]
- ]
- },
- {
- "input": "&models",
- "description": "Bad named entity: models without a semi-colon",
- "output": [
- [
- "Character",
- "&models"
- ]
- ]
- },
- {
- "input": "⊧",
- "description": "Named entity: models; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a7"
- ]
- ]
- },
- {
- "input": "&mopf",
- "description": "Bad named entity: mopf without a semi-colon",
- "output": [
- [
- "Character",
- "&mopf"
- ]
- ]
- },
- {
- "input": "𝕞",
- "description": "Named entity: mopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd5e"
- ]
- ]
- },
- {
- "input": "&mp",
- "description": "Bad named entity: mp without a semi-colon",
- "output": [
- [
- "Character",
- "&mp"
- ]
- ]
- },
- {
- "input": "∓",
- "description": "Named entity: mp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2213"
- ]
- ]
- },
- {
- "input": "&mscr",
- "description": "Bad named entity: mscr without a semi-colon",
- "output": [
- [
- "Character",
- "&mscr"
- ]
- ]
- },
- {
- "input": "𝓂",
- "description": "Named entity: mscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc2"
- ]
- ]
- },
- {
- "input": "&mstpos",
- "description": "Bad named entity: mstpos without a semi-colon",
- "output": [
- [
- "Character",
- "&mstpos"
- ]
- ]
- },
- {
- "input": "∾",
- "description": "Named entity: mstpos; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223e"
- ]
- ]
- },
- {
- "input": "&mu",
- "description": "Bad named entity: mu without a semi-colon",
- "output": [
- [
- "Character",
- "&mu"
- ]
- ]
- },
- {
- "input": "μ",
- "description": "Named entity: mu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03bc"
- ]
- ]
- },
- {
- "input": "&multimap",
- "description": "Bad named entity: multimap without a semi-colon",
- "output": [
- [
- "Character",
- "&multimap"
- ]
- ]
- },
- {
- "input": "⊸",
- "description": "Named entity: multimap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b8"
- ]
- ]
- },
- {
- "input": "&mumap",
- "description": "Bad named entity: mumap without a semi-colon",
- "output": [
- [
- "Character",
- "&mumap"
- ]
- ]
- },
- {
- "input": "⊸",
- "description": "Named entity: mumap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b8"
- ]
- ]
- },
- {
- "input": "&nGg",
- "description": "Bad named entity: nGg without a semi-colon",
- "output": [
- [
- "Character",
- "&nGg"
- ]
- ]
- },
- {
- "input": "⋙̸",
- "description": "Named entity: nGg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d9\u0338"
- ]
- ]
- },
- {
- "input": "&nGt",
- "description": "Bad named entity: nGt without a semi-colon",
- "output": [
- [
- "Character",
- "&nGt"
- ]
- ]
- },
- {
- "input": "≫⃒",
- "description": "Named entity: nGt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226b\u20d2"
- ]
- ]
- },
- {
- "input": "&nGtv",
- "description": "Bad named entity: nGtv without a semi-colon",
- "output": [
- [
- "Character",
- "&nGtv"
- ]
- ]
- },
- {
- "input": "≫̸",
- "description": "Named entity: nGtv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226b\u0338"
- ]
- ]
- },
- {
- "input": "&nLeftarrow",
- "description": "Bad named entity: nLeftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&nLeftarrow"
- ]
- ]
- },
- {
- "input": "⇍",
- "description": "Named entity: nLeftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cd"
- ]
- ]
- },
- {
- "input": "&nLeftrightarrow",
- "description": "Bad named entity: nLeftrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&nLeftrightarrow"
- ]
- ]
- },
- {
- "input": "⇎",
- "description": "Named entity: nLeftrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ce"
- ]
- ]
- },
- {
- "input": "&nLl",
- "description": "Bad named entity: nLl without a semi-colon",
- "output": [
- [
- "Character",
- "&nLl"
- ]
- ]
- },
- {
- "input": "⋘̸",
- "description": "Named entity: nLl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d8\u0338"
- ]
- ]
- },
- {
- "input": "&nLt",
- "description": "Bad named entity: nLt without a semi-colon",
- "output": [
- [
- "Character",
- "&nLt"
- ]
- ]
- },
- {
- "input": "≪⃒",
- "description": "Named entity: nLt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226a\u20d2"
- ]
- ]
- },
- {
- "input": "&nLtv",
- "description": "Bad named entity: nLtv without a semi-colon",
- "output": [
- [
- "Character",
- "&nLtv"
- ]
- ]
- },
- {
- "input": "≪̸",
- "description": "Named entity: nLtv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226a\u0338"
- ]
- ]
- },
- {
- "input": "&nRightarrow",
- "description": "Bad named entity: nRightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&nRightarrow"
- ]
- ]
- },
- {
- "input": "⇏",
- "description": "Named entity: nRightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cf"
- ]
- ]
- },
- {
- "input": "&nVDash",
- "description": "Bad named entity: nVDash without a semi-colon",
- "output": [
- [
- "Character",
- "&nVDash"
- ]
- ]
- },
- {
- "input": "⊯",
- "description": "Named entity: nVDash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22af"
- ]
- ]
- },
- {
- "input": "&nVdash",
- "description": "Bad named entity: nVdash without a semi-colon",
- "output": [
- [
- "Character",
- "&nVdash"
- ]
- ]
- },
- {
- "input": "⊮",
- "description": "Named entity: nVdash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ae"
- ]
- ]
- },
- {
- "input": "&nabla",
- "description": "Bad named entity: nabla without a semi-colon",
- "output": [
- [
- "Character",
- "&nabla"
- ]
- ]
- },
- {
- "input": "∇",
- "description": "Named entity: nabla; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2207"
- ]
- ]
- },
- {
- "input": "&nacute",
- "description": "Bad named entity: nacute without a semi-colon",
- "output": [
- [
- "Character",
- "&nacute"
- ]
- ]
- },
- {
- "input": "ń",
- "description": "Named entity: nacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0144"
- ]
- ]
- },
- {
- "input": "&nang",
- "description": "Bad named entity: nang without a semi-colon",
- "output": [
- [
- "Character",
- "&nang"
- ]
- ]
- },
- {
- "input": "∠⃒",
- "description": "Named entity: nang; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2220\u20d2"
- ]
- ]
- },
- {
- "input": "&nap",
- "description": "Bad named entity: nap without a semi-colon",
- "output": [
- [
- "Character",
- "&nap"
- ]
- ]
- },
- {
- "input": "≉",
- "description": "Named entity: nap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2249"
- ]
- ]
- },
- {
- "input": "&napE",
- "description": "Bad named entity: napE without a semi-colon",
- "output": [
- [
- "Character",
- "&napE"
- ]
- ]
- },
- {
- "input": "⩰̸",
- "description": "Named entity: napE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a70\u0338"
- ]
- ]
- },
- {
- "input": "&napid",
- "description": "Bad named entity: napid without a semi-colon",
- "output": [
- [
- "Character",
- "&napid"
- ]
- ]
- },
- {
- "input": "≋̸",
- "description": "Named entity: napid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224b\u0338"
- ]
- ]
- },
- {
- "input": "&napos",
- "description": "Bad named entity: napos without a semi-colon",
- "output": [
- [
- "Character",
- "&napos"
- ]
- ]
- },
- {
- "input": "ʼn",
- "description": "Named entity: napos; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0149"
- ]
- ]
- },
- {
- "input": "&napprox",
- "description": "Bad named entity: napprox without a semi-colon",
- "output": [
- [
- "Character",
- "&napprox"
- ]
- ]
- },
- {
- "input": "≉",
- "description": "Named entity: napprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2249"
- ]
- ]
- },
- {
- "input": "&natur",
- "description": "Bad named entity: natur without a semi-colon",
- "output": [
- [
- "Character",
- "&natur"
- ]
- ]
- },
- {
- "input": "♮",
- "description": "Named entity: natur; with a semi-colon",
- "output": [
- [
- "Character",
- "\u266e"
- ]
- ]
- },
- {
- "input": "&natural",
- "description": "Bad named entity: natural without a semi-colon",
- "output": [
- [
- "Character",
- "&natural"
- ]
- ]
- },
- {
- "input": "♮",
- "description": "Named entity: natural; with a semi-colon",
- "output": [
- [
- "Character",
- "\u266e"
- ]
- ]
- },
- {
- "input": "&naturals",
- "description": "Bad named entity: naturals without a semi-colon",
- "output": [
- [
- "Character",
- "&naturals"
- ]
- ]
- },
- {
- "input": "ℕ",
- "description": "Named entity: naturals; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2115"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: nbsp without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a0"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: nbsp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a0"
- ]
- ]
- },
- {
- "input": "&nbump",
- "description": "Bad named entity: nbump without a semi-colon",
- "output": [
- [
- "Character",
- "&nbump"
- ]
- ]
- },
- {
- "input": "≎̸",
- "description": "Named entity: nbump; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224e\u0338"
- ]
- ]
- },
- {
- "input": "&nbumpe",
- "description": "Bad named entity: nbumpe without a semi-colon",
- "output": [
- [
- "Character",
- "&nbumpe"
- ]
- ]
- },
- {
- "input": "≏̸",
- "description": "Named entity: nbumpe; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224f\u0338"
- ]
- ]
- },
- {
- "input": "&ncap",
- "description": "Bad named entity: ncap without a semi-colon",
- "output": [
- [
- "Character",
- "&ncap"
- ]
- ]
- },
- {
- "input": "⩃",
- "description": "Named entity: ncap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a43"
- ]
- ]
- },
- {
- "input": "&ncaron",
- "description": "Bad named entity: ncaron without a semi-colon",
- "output": [
- [
- "Character",
- "&ncaron"
- ]
- ]
- },
- {
- "input": "ň",
- "description": "Named entity: ncaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0148"
- ]
- ]
- },
- {
- "input": "&ncedil",
- "description": "Bad named entity: ncedil without a semi-colon",
- "output": [
- [
- "Character",
- "&ncedil"
- ]
- ]
- },
- {
- "input": "ņ",
- "description": "Named entity: ncedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0146"
- ]
- ]
- },
- {
- "input": "&ncong",
- "description": "Bad named entity: ncong without a semi-colon",
- "output": [
- [
- "Character",
- "&ncong"
- ]
- ]
- },
- {
- "input": "≇",
- "description": "Named entity: ncong; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2247"
- ]
- ]
- },
- {
- "input": "&ncongdot",
- "description": "Bad named entity: ncongdot without a semi-colon",
- "output": [
- [
- "Character",
- "&ncongdot"
- ]
- ]
- },
- {
- "input": "⩭̸",
- "description": "Named entity: ncongdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a6d\u0338"
- ]
- ]
- },
- {
- "input": "&ncup",
- "description": "Bad named entity: ncup without a semi-colon",
- "output": [
- [
- "Character",
- "&ncup"
- ]
- ]
- },
- {
- "input": "⩂",
- "description": "Named entity: ncup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a42"
- ]
- ]
- },
- {
- "input": "&ncy",
- "description": "Bad named entity: ncy without a semi-colon",
- "output": [
- [
- "Character",
- "&ncy"
- ]
- ]
- },
- {
- "input": "н",
- "description": "Named entity: ncy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u043d"
- ]
- ]
- },
- {
- "input": "&ndash",
- "description": "Bad named entity: ndash without a semi-colon",
- "output": [
- [
- "Character",
- "&ndash"
- ]
- ]
- },
- {
- "input": "–",
- "description": "Named entity: ndash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2013"
- ]
- ]
- },
- {
- "input": "&ne",
- "description": "Bad named entity: ne without a semi-colon",
- "output": [
- [
- "Character",
- "&ne"
- ]
- ]
- },
- {
- "input": "≠",
- "description": "Named entity: ne; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2260"
- ]
- ]
- },
- {
- "input": "&neArr",
- "description": "Bad named entity: neArr without a semi-colon",
- "output": [
- [
- "Character",
- "&neArr"
- ]
- ]
- },
- {
- "input": "⇗",
- "description": "Named entity: neArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d7"
- ]
- ]
- },
- {
- "input": "&nearhk",
- "description": "Bad named entity: nearhk without a semi-colon",
- "output": [
- [
- "Character",
- "&nearhk"
- ]
- ]
- },
- {
- "input": "⤤",
- "description": "Named entity: nearhk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2924"
- ]
- ]
- },
- {
- "input": "&nearr",
- "description": "Bad named entity: nearr without a semi-colon",
- "output": [
- [
- "Character",
- "&nearr"
- ]
- ]
- },
- {
- "input": "↗",
- "description": "Named entity: nearr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2197"
- ]
- ]
- },
- {
- "input": "&nearrow",
- "description": "Bad named entity: nearrow without a semi-colon",
- "output": [
- [
- "Character",
- "&nearrow"
- ]
- ]
- },
- {
- "input": "↗",
- "description": "Named entity: nearrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2197"
- ]
- ]
- },
- {
- "input": "&nedot",
- "description": "Bad named entity: nedot without a semi-colon",
- "output": [
- [
- "Character",
- "&nedot"
- ]
- ]
- },
- {
- "input": "≐̸",
- "description": "Named entity: nedot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2250\u0338"
- ]
- ]
- },
- {
- "input": "&nequiv",
- "description": "Bad named entity: nequiv without a semi-colon",
- "output": [
- [
- "Character",
- "&nequiv"
- ]
- ]
- },
- {
- "input": "≢",
- "description": "Named entity: nequiv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2262"
- ]
- ]
- },
- {
- "input": "&nesear",
- "description": "Bad named entity: nesear without a semi-colon",
- "output": [
- [
- "Character",
- "&nesear"
- ]
- ]
- },
- {
- "input": "⤨",
- "description": "Named entity: nesear; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2928"
- ]
- ]
- },
- {
- "input": "&nesim",
- "description": "Bad named entity: nesim without a semi-colon",
- "output": [
- [
- "Character",
- "&nesim"
- ]
- ]
- },
- {
- "input": "≂̸",
- "description": "Named entity: nesim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2242\u0338"
- ]
- ]
- },
- {
- "input": "&nexist",
- "description": "Bad named entity: nexist without a semi-colon",
- "output": [
- [
- "Character",
- "&nexist"
- ]
- ]
- },
- {
- "input": "∄",
- "description": "Named entity: nexist; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2204"
- ]
- ]
- },
- {
- "input": "&nexists",
- "description": "Bad named entity: nexists without a semi-colon",
- "output": [
- [
- "Character",
- "&nexists"
- ]
- ]
- },
- {
- "input": "∄",
- "description": "Named entity: nexists; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2204"
- ]
- ]
- },
- {
- "input": "&nfr",
- "description": "Bad named entity: nfr without a semi-colon",
- "output": [
- [
- "Character",
- "&nfr"
- ]
- ]
- },
- {
- "input": "𝔫",
- "description": "Named entity: nfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd2b"
- ]
- ]
- },
- {
- "input": "&ngE",
- "description": "Bad named entity: ngE without a semi-colon",
- "output": [
- [
- "Character",
- "&ngE"
- ]
- ]
- },
- {
- "input": "≧̸",
- "description": "Named entity: ngE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2267\u0338"
- ]
- ]
- },
- {
- "input": "&nge",
- "description": "Bad named entity: nge without a semi-colon",
- "output": [
- [
- "Character",
- "&nge"
- ]
- ]
- },
- {
- "input": "≱",
- "description": "Named entity: nge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2271"
- ]
- ]
- },
- {
- "input": "&ngeq",
- "description": "Bad named entity: ngeq without a semi-colon",
- "output": [
- [
- "Character",
- "&ngeq"
- ]
- ]
- },
- {
- "input": "≱",
- "description": "Named entity: ngeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2271"
- ]
- ]
- },
- {
- "input": "&ngeqq",
- "description": "Bad named entity: ngeqq without a semi-colon",
- "output": [
- [
- "Character",
- "&ngeqq"
- ]
- ]
- },
- {
- "input": "≧̸",
- "description": "Named entity: ngeqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2267\u0338"
- ]
- ]
- },
- {
- "input": "&ngeqslant",
- "description": "Bad named entity: ngeqslant without a semi-colon",
- "output": [
- [
- "Character",
- "&ngeqslant"
- ]
- ]
- },
- {
- "input": "⩾̸",
- "description": "Named entity: ngeqslant; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7e\u0338"
- ]
- ]
- },
- {
- "input": "&nges",
- "description": "Bad named entity: nges without a semi-colon",
- "output": [
- [
- "Character",
- "&nges"
- ]
- ]
- },
- {
- "input": "⩾̸",
- "description": "Named entity: nges; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7e\u0338"
- ]
- ]
- },
- {
- "input": "&ngsim",
- "description": "Bad named entity: ngsim without a semi-colon",
- "output": [
- [
- "Character",
- "&ngsim"
- ]
- ]
- },
- {
- "input": "≵",
- "description": "Named entity: ngsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2275"
- ]
- ]
- },
- {
- "input": "&ngt",
- "description": "Bad named entity: ngt without a semi-colon",
- "output": [
- [
- "Character",
- "&ngt"
- ]
- ]
- },
- {
- "input": "≯",
- "description": "Named entity: ngt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226f"
- ]
- ]
- },
- {
- "input": "&ngtr",
- "description": "Bad named entity: ngtr without a semi-colon",
- "output": [
- [
- "Character",
- "&ngtr"
- ]
- ]
- },
- {
- "input": "≯",
- "description": "Named entity: ngtr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226f"
- ]
- ]
- },
- {
- "input": "&nhArr",
- "description": "Bad named entity: nhArr without a semi-colon",
- "output": [
- [
- "Character",
- "&nhArr"
- ]
- ]
- },
- {
- "input": "⇎",
- "description": "Named entity: nhArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ce"
- ]
- ]
- },
- {
- "input": "&nharr",
- "description": "Bad named entity: nharr without a semi-colon",
- "output": [
- [
- "Character",
- "&nharr"
- ]
- ]
- },
- {
- "input": "↮",
- "description": "Named entity: nharr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ae"
- ]
- ]
- },
- {
- "input": "&nhpar",
- "description": "Bad named entity: nhpar without a semi-colon",
- "output": [
- [
- "Character",
- "&nhpar"
- ]
- ]
- },
- {
- "input": "⫲",
- "description": "Named entity: nhpar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2af2"
- ]
- ]
- },
- {
- "input": "&ni",
- "description": "Bad named entity: ni without a semi-colon",
- "output": [
- [
- "Character",
- "&ni"
- ]
- ]
- },
- {
- "input": "∋",
- "description": "Named entity: ni; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220b"
- ]
- ]
- },
- {
- "input": "&nis",
- "description": "Bad named entity: nis without a semi-colon",
- "output": [
- [
- "Character",
- "&nis"
- ]
- ]
- },
- {
- "input": "⋼",
- "description": "Named entity: nis; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22fc"
- ]
- ]
- },
- {
- "input": "&nisd",
- "description": "Bad named entity: nisd without a semi-colon",
- "output": [
- [
- "Character",
- "&nisd"
- ]
- ]
- },
- {
- "input": "⋺",
- "description": "Named entity: nisd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22fa"
- ]
- ]
- },
- {
- "input": "&niv",
- "description": "Bad named entity: niv without a semi-colon",
- "output": [
- [
- "Character",
- "&niv"
- ]
- ]
- },
- {
- "input": "∋",
- "description": "Named entity: niv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220b"
- ]
- ]
- },
- {
- "input": "&njcy",
- "description": "Bad named entity: njcy without a semi-colon",
- "output": [
- [
- "Character",
- "&njcy"
- ]
- ]
- },
- {
- "input": "њ",
- "description": "Named entity: njcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u045a"
- ]
- ]
- },
- {
- "input": "&nlArr",
- "description": "Bad named entity: nlArr without a semi-colon",
- "output": [
- [
- "Character",
- "&nlArr"
- ]
- ]
- },
- {
- "input": "⇍",
- "description": "Named entity: nlArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cd"
- ]
- ]
- },
- {
- "input": "&nlE",
- "description": "Bad named entity: nlE without a semi-colon",
- "output": [
- [
- "Character",
- "&nlE"
- ]
- ]
- },
- {
- "input": "≦̸",
- "description": "Named entity: nlE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2266\u0338"
- ]
- ]
- },
- {
- "input": "&nlarr",
- "description": "Bad named entity: nlarr without a semi-colon",
- "output": [
- [
- "Character",
- "&nlarr"
- ]
- ]
- },
- {
- "input": "↚",
- "description": "Named entity: nlarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219a"
- ]
- ]
- },
- {
- "input": "&nldr",
- "description": "Bad named entity: nldr without a semi-colon",
- "output": [
- [
- "Character",
- "&nldr"
- ]
- ]
- },
- {
- "input": "‥",
- "description": "Named entity: nldr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2025"
- ]
- ]
- },
- {
- "input": "&nle",
- "description": "Bad named entity: nle without a semi-colon",
- "output": [
- [
- "Character",
- "&nle"
- ]
- ]
- },
- {
- "input": "≰",
- "description": "Named entity: nle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2270"
- ]
- ]
- },
- {
- "input": "&nleftarrow",
- "description": "Bad named entity: nleftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&nleftarrow"
- ]
- ]
- },
- {
- "input": "↚",
- "description": "Named entity: nleftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219a"
- ]
- ]
- },
- {
- "input": "&nleftrightarrow",
- "description": "Bad named entity: nleftrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&nleftrightarrow"
- ]
- ]
- },
- {
- "input": "↮",
- "description": "Named entity: nleftrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ae"
- ]
- ]
- },
- {
- "input": "&nleq",
- "description": "Bad named entity: nleq without a semi-colon",
- "output": [
- [
- "Character",
- "&nleq"
- ]
- ]
- },
- {
- "input": "≰",
- "description": "Named entity: nleq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2270"
- ]
- ]
- },
- {
- "input": "&nleqq",
- "description": "Bad named entity: nleqq without a semi-colon",
- "output": [
- [
- "Character",
- "&nleqq"
- ]
- ]
- },
- {
- "input": "≦̸",
- "description": "Named entity: nleqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2266\u0338"
- ]
- ]
- },
- {
- "input": "&nleqslant",
- "description": "Bad named entity: nleqslant without a semi-colon",
- "output": [
- [
- "Character",
- "&nleqslant"
- ]
- ]
- },
- {
- "input": "⩽̸",
- "description": "Named entity: nleqslant; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7d\u0338"
- ]
- ]
- },
- {
- "input": "&nles",
- "description": "Bad named entity: nles without a semi-colon",
- "output": [
- [
- "Character",
- "&nles"
- ]
- ]
- },
- {
- "input": "⩽̸",
- "description": "Named entity: nles; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a7d\u0338"
- ]
- ]
- },
- {
- "input": "&nless",
- "description": "Bad named entity: nless without a semi-colon",
- "output": [
- [
- "Character",
- "&nless"
- ]
- ]
- },
- {
- "input": "≮",
- "description": "Named entity: nless; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226e"
- ]
- ]
- },
- {
- "input": "&nlsim",
- "description": "Bad named entity: nlsim without a semi-colon",
- "output": [
- [
- "Character",
- "&nlsim"
- ]
- ]
- },
- {
- "input": "≴",
- "description": "Named entity: nlsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2274"
- ]
- ]
- },
- {
- "input": "&nlt",
- "description": "Bad named entity: nlt without a semi-colon",
- "output": [
- [
- "Character",
- "&nlt"
- ]
- ]
- },
- {
- "input": "≮",
- "description": "Named entity: nlt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226e"
- ]
- ]
- },
- {
- "input": "&nltri",
- "description": "Bad named entity: nltri without a semi-colon",
- "output": [
- [
- "Character",
- "&nltri"
- ]
- ]
- },
- {
- "input": "⋪",
- "description": "Named entity: nltri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ea"
- ]
- ]
- },
- {
- "input": "&nltrie",
- "description": "Bad named entity: nltrie without a semi-colon",
- "output": [
- [
- "Character",
- "&nltrie"
- ]
- ]
- },
- {
- "input": "⋬",
- "description": "Named entity: nltrie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ec"
- ]
- ]
- },
- {
- "input": "&nmid",
- "description": "Bad named entity: nmid without a semi-colon",
- "output": [
- [
- "Character",
- "&nmid"
- ]
- ]
- },
- {
- "input": "∤",
- "description": "Named entity: nmid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2224"
- ]
- ]
- },
- {
- "input": "&nopf",
- "description": "Bad named entity: nopf without a semi-colon",
- "output": [
- [
- "Character",
- "&nopf"
- ]
- ]
- },
- {
- "input": "𝕟",
- "description": "Named entity: nopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd5f"
- ]
- ]
- },
- {
- "input": "¬",
- "description": "Named entity: not without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ac"
- ]
- ]
- },
- {
- "input": "¬",
- "description": "Named entity: not; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ac"
- ]
- ]
- },
- {
- "input": "∉",
- "description": "Named entity: notin; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2209"
- ]
- ]
- },
- {
- "input": "⋹̸",
- "description": "Named entity: notinE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f9\u0338"
- ]
- ]
- },
- {
- "input": "⋵̸",
- "description": "Named entity: notindot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f5\u0338"
- ]
- ]
- },
- {
- "input": "∉",
- "description": "Named entity: notinva; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2209"
- ]
- ]
- },
- {
- "input": "⋷",
- "description": "Named entity: notinvb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f7"
- ]
- ]
- },
- {
- "input": "⋶",
- "description": "Named entity: notinvc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f6"
- ]
- ]
- },
- {
- "input": "∌",
- "description": "Named entity: notni; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220c"
- ]
- ]
- },
- {
- "input": "∌",
- "description": "Named entity: notniva; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220c"
- ]
- ]
- },
- {
- "input": "⋾",
- "description": "Named entity: notnivb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22fe"
- ]
- ]
- },
- {
- "input": "⋽",
- "description": "Named entity: notnivc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22fd"
- ]
- ]
- },
- {
- "input": "&npar",
- "description": "Bad named entity: npar without a semi-colon",
- "output": [
- [
- "Character",
- "&npar"
- ]
- ]
- },
- {
- "input": "∦",
- "description": "Named entity: npar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2226"
- ]
- ]
- },
- {
- "input": "&nparallel",
- "description": "Bad named entity: nparallel without a semi-colon",
- "output": [
- [
- "Character",
- "&nparallel"
- ]
- ]
- },
- {
- "input": "∦",
- "description": "Named entity: nparallel; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2226"
- ]
- ]
- },
- {
- "input": "&nparsl",
- "description": "Bad named entity: nparsl without a semi-colon",
- "output": [
- [
- "Character",
- "&nparsl"
- ]
- ]
- },
- {
- "input": "⫽⃥",
- "description": "Named entity: nparsl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2afd\u20e5"
- ]
- ]
- },
- {
- "input": "&npart",
- "description": "Bad named entity: npart without a semi-colon",
- "output": [
- [
- "Character",
- "&npart"
- ]
- ]
- },
- {
- "input": "∂̸",
- "description": "Named entity: npart; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2202\u0338"
- ]
- ]
- },
- {
- "input": "&npolint",
- "description": "Bad named entity: npolint without a semi-colon",
- "output": [
- [
- "Character",
- "&npolint"
- ]
- ]
- },
- {
- "input": "⨔",
- "description": "Named entity: npolint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a14"
- ]
- ]
- },
- {
- "input": "&npr",
- "description": "Bad named entity: npr without a semi-colon",
- "output": [
- [
- "Character",
- "&npr"
- ]
- ]
- },
- {
- "input": "⊀",
- "description": "Named entity: npr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2280"
- ]
- ]
- },
- {
- "input": "&nprcue",
- "description": "Bad named entity: nprcue without a semi-colon",
- "output": [
- [
- "Character",
- "&nprcue"
- ]
- ]
- },
- {
- "input": "⋠",
- "description": "Named entity: nprcue; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e0"
- ]
- ]
- },
- {
- "input": "&npre",
- "description": "Bad named entity: npre without a semi-colon",
- "output": [
- [
- "Character",
- "&npre"
- ]
- ]
- },
- {
- "input": "⪯̸",
- "description": "Named entity: npre; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aaf\u0338"
- ]
- ]
- },
- {
- "input": "&nprec",
- "description": "Bad named entity: nprec without a semi-colon",
- "output": [
- [
- "Character",
- "&nprec"
- ]
- ]
- },
- {
- "input": "⊀",
- "description": "Named entity: nprec; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2280"
- ]
- ]
- },
- {
- "input": "&npreceq",
- "description": "Bad named entity: npreceq without a semi-colon",
- "output": [
- [
- "Character",
- "&npreceq"
- ]
- ]
- },
- {
- "input": "⪯̸",
- "description": "Named entity: npreceq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aaf\u0338"
- ]
- ]
- },
- {
- "input": "&nrArr",
- "description": "Bad named entity: nrArr without a semi-colon",
- "output": [
- [
- "Character",
- "&nrArr"
- ]
- ]
- },
- {
- "input": "⇏",
- "description": "Named entity: nrArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cf"
- ]
- ]
- },
- {
- "input": "&nrarr",
- "description": "Bad named entity: nrarr without a semi-colon",
- "output": [
- [
- "Character",
- "&nrarr"
- ]
- ]
- },
- {
- "input": "↛",
- "description": "Named entity: nrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219b"
- ]
- ]
- },
- {
- "input": "&nrarrc",
- "description": "Bad named entity: nrarrc without a semi-colon",
- "output": [
- [
- "Character",
- "&nrarrc"
- ]
- ]
- },
- {
- "input": "⤳̸",
- "description": "Named entity: nrarrc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2933\u0338"
- ]
- ]
- },
- {
- "input": "&nrarrw",
- "description": "Bad named entity: nrarrw without a semi-colon",
- "output": [
- [
- "Character",
- "&nrarrw"
- ]
- ]
- },
- {
- "input": "↝̸",
- "description": "Named entity: nrarrw; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219d\u0338"
- ]
- ]
- },
- {
- "input": "&nrightarrow",
- "description": "Bad named entity: nrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&nrightarrow"
- ]
- ]
- },
- {
- "input": "↛",
- "description": "Named entity: nrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219b"
- ]
- ]
- },
- {
- "input": "&nrtri",
- "description": "Bad named entity: nrtri without a semi-colon",
- "output": [
- [
- "Character",
- "&nrtri"
- ]
- ]
- },
- {
- "input": "⋫",
- "description": "Named entity: nrtri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22eb"
- ]
- ]
- },
- {
- "input": "&nrtrie",
- "description": "Bad named entity: nrtrie without a semi-colon",
- "output": [
- [
- "Character",
- "&nrtrie"
- ]
- ]
- },
- {
- "input": "⋭",
- "description": "Named entity: nrtrie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ed"
- ]
- ]
- },
- {
- "input": "&nsc",
- "description": "Bad named entity: nsc without a semi-colon",
- "output": [
- [
- "Character",
- "&nsc"
- ]
- ]
- },
- {
- "input": "⊁",
- "description": "Named entity: nsc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2281"
- ]
- ]
- },
- {
- "input": "&nsccue",
- "description": "Bad named entity: nsccue without a semi-colon",
- "output": [
- [
- "Character",
- "&nsccue"
- ]
- ]
- },
- {
- "input": "⋡",
- "description": "Named entity: nsccue; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e1"
- ]
- ]
- },
- {
- "input": "&nsce",
- "description": "Bad named entity: nsce without a semi-colon",
- "output": [
- [
- "Character",
- "&nsce"
- ]
- ]
- },
- {
- "input": "⪰̸",
- "description": "Named entity: nsce; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab0\u0338"
- ]
- ]
- },
- {
- "input": "&nscr",
- "description": "Bad named entity: nscr without a semi-colon",
- "output": [
- [
- "Character",
- "&nscr"
- ]
- ]
- },
- {
- "input": "𝓃",
- "description": "Named entity: nscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc3"
- ]
- ]
- },
- {
- "input": "&nshortmid",
- "description": "Bad named entity: nshortmid without a semi-colon",
- "output": [
- [
- "Character",
- "&nshortmid"
- ]
- ]
- },
- {
- "input": "∤",
- "description": "Named entity: nshortmid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2224"
- ]
- ]
- },
- {
- "input": "&nshortparallel",
- "description": "Bad named entity: nshortparallel without a semi-colon",
- "output": [
- [
- "Character",
- "&nshortparallel"
- ]
- ]
- },
- {
- "input": "∦",
- "description": "Named entity: nshortparallel; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2226"
- ]
- ]
- },
- {
- "input": "&nsim",
- "description": "Bad named entity: nsim without a semi-colon",
- "output": [
- [
- "Character",
- "&nsim"
- ]
- ]
- },
- {
- "input": "≁",
- "description": "Named entity: nsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2241"
- ]
- ]
- },
- {
- "input": "&nsime",
- "description": "Bad named entity: nsime without a semi-colon",
- "output": [
- [
- "Character",
- "&nsime"
- ]
- ]
- },
- {
- "input": "≄",
- "description": "Named entity: nsime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2244"
- ]
- ]
- },
- {
- "input": "&nsimeq",
- "description": "Bad named entity: nsimeq without a semi-colon",
- "output": [
- [
- "Character",
- "&nsimeq"
- ]
- ]
- },
- {
- "input": "≄",
- "description": "Named entity: nsimeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2244"
- ]
- ]
- },
- {
- "input": "&nsmid",
- "description": "Bad named entity: nsmid without a semi-colon",
- "output": [
- [
- "Character",
- "&nsmid"
- ]
- ]
- },
- {
- "input": "∤",
- "description": "Named entity: nsmid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2224"
- ]
- ]
- },
- {
- "input": "&nspar",
- "description": "Bad named entity: nspar without a semi-colon",
- "output": [
- [
- "Character",
- "&nspar"
- ]
- ]
- },
- {
- "input": "∦",
- "description": "Named entity: nspar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2226"
- ]
- ]
- },
- {
- "input": "&nsqsube",
- "description": "Bad named entity: nsqsube without a semi-colon",
- "output": [
- [
- "Character",
- "&nsqsube"
- ]
- ]
- },
- {
- "input": "⋢",
- "description": "Named entity: nsqsube; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e2"
- ]
- ]
- },
- {
- "input": "&nsqsupe",
- "description": "Bad named entity: nsqsupe without a semi-colon",
- "output": [
- [
- "Character",
- "&nsqsupe"
- ]
- ]
- },
- {
- "input": "⋣",
- "description": "Named entity: nsqsupe; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e3"
- ]
- ]
- },
- {
- "input": "&nsub",
- "description": "Bad named entity: nsub without a semi-colon",
- "output": [
- [
- "Character",
- "&nsub"
- ]
- ]
- },
- {
- "input": "⊄",
- "description": "Named entity: nsub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2284"
- ]
- ]
- },
- {
- "input": "&nsubE",
- "description": "Bad named entity: nsubE without a semi-colon",
- "output": [
- [
- "Character",
- "&nsubE"
- ]
- ]
- },
- {
- "input": "⫅̸",
- "description": "Named entity: nsubE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac5\u0338"
- ]
- ]
- },
- {
- "input": "&nsube",
- "description": "Bad named entity: nsube without a semi-colon",
- "output": [
- [
- "Character",
- "&nsube"
- ]
- ]
- },
- {
- "input": "⊈",
- "description": "Named entity: nsube; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2288"
- ]
- ]
- },
- {
- "input": "&nsubset",
- "description": "Bad named entity: nsubset without a semi-colon",
- "output": [
- [
- "Character",
- "&nsubset"
- ]
- ]
- },
- {
- "input": "⊂⃒",
- "description": "Named entity: nsubset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2282\u20d2"
- ]
- ]
- },
- {
- "input": "&nsubseteq",
- "description": "Bad named entity: nsubseteq without a semi-colon",
- "output": [
- [
- "Character",
- "&nsubseteq"
- ]
- ]
- },
- {
- "input": "⊈",
- "description": "Named entity: nsubseteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2288"
- ]
- ]
- },
- {
- "input": "&nsubseteqq",
- "description": "Bad named entity: nsubseteqq without a semi-colon",
- "output": [
- [
- "Character",
- "&nsubseteqq"
- ]
- ]
- },
- {
- "input": "⫅̸",
- "description": "Named entity: nsubseteqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac5\u0338"
- ]
- ]
- },
- {
- "input": "&nsucc",
- "description": "Bad named entity: nsucc without a semi-colon",
- "output": [
- [
- "Character",
- "&nsucc"
- ]
- ]
- },
- {
- "input": "⊁",
- "description": "Named entity: nsucc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2281"
- ]
- ]
- },
- {
- "input": "&nsucceq",
- "description": "Bad named entity: nsucceq without a semi-colon",
- "output": [
- [
- "Character",
- "&nsucceq"
- ]
- ]
- },
- {
- "input": "⪰̸",
- "description": "Named entity: nsucceq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab0\u0338"
- ]
- ]
- },
- {
- "input": "&nsup",
- "description": "Bad named entity: nsup without a semi-colon",
- "output": [
- [
- "Character",
- "&nsup"
- ]
- ]
- },
- {
- "input": "⊅",
- "description": "Named entity: nsup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2285"
- ]
- ]
- },
- {
- "input": "&nsupE",
- "description": "Bad named entity: nsupE without a semi-colon",
- "output": [
- [
- "Character",
- "&nsupE"
- ]
- ]
- },
- {
- "input": "⫆̸",
- "description": "Named entity: nsupE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac6\u0338"
- ]
- ]
- },
- {
- "input": "&nsupe",
- "description": "Bad named entity: nsupe without a semi-colon",
- "output": [
- [
- "Character",
- "&nsupe"
- ]
- ]
- },
- {
- "input": "⊉",
- "description": "Named entity: nsupe; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2289"
- ]
- ]
- },
- {
- "input": "&nsupset",
- "description": "Bad named entity: nsupset without a semi-colon",
- "output": [
- [
- "Character",
- "&nsupset"
- ]
- ]
- },
- {
- "input": "⊃⃒",
- "description": "Named entity: nsupset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2283\u20d2"
- ]
- ]
- },
- {
- "input": "&nsupseteq",
- "description": "Bad named entity: nsupseteq without a semi-colon",
- "output": [
- [
- "Character",
- "&nsupseteq"
- ]
- ]
- },
- {
- "input": "⊉",
- "description": "Named entity: nsupseteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2289"
- ]
- ]
- },
- {
- "input": "&nsupseteqq",
- "description": "Bad named entity: nsupseteqq without a semi-colon",
- "output": [
- [
- "Character",
- "&nsupseteqq"
- ]
- ]
- },
- {
- "input": "⫆̸",
- "description": "Named entity: nsupseteqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac6\u0338"
- ]
- ]
- },
- {
- "input": "&ntgl",
- "description": "Bad named entity: ntgl without a semi-colon",
- "output": [
- [
- "Character",
- "&ntgl"
- ]
- ]
- },
- {
- "input": "≹",
- "description": "Named entity: ntgl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2279"
- ]
- ]
- },
- {
- "input": "ñ",
- "description": "Named entity: ntilde without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f1"
- ]
- ]
- },
- {
- "input": "ñ",
- "description": "Named entity: ntilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f1"
- ]
- ]
- },
- {
- "input": "&ntlg",
- "description": "Bad named entity: ntlg without a semi-colon",
- "output": [
- [
- "Character",
- "&ntlg"
- ]
- ]
- },
- {
- "input": "≸",
- "description": "Named entity: ntlg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2278"
- ]
- ]
- },
- {
- "input": "&ntriangleleft",
- "description": "Bad named entity: ntriangleleft without a semi-colon",
- "output": [
- [
- "Character",
- "&ntriangleleft"
- ]
- ]
- },
- {
- "input": "⋪",
- "description": "Named entity: ntriangleleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ea"
- ]
- ]
- },
- {
- "input": "&ntrianglelefteq",
- "description": "Bad named entity: ntrianglelefteq without a semi-colon",
- "output": [
- [
- "Character",
- "&ntrianglelefteq"
- ]
- ]
- },
- {
- "input": "⋬",
- "description": "Named entity: ntrianglelefteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ec"
- ]
- ]
- },
- {
- "input": "&ntriangleright",
- "description": "Bad named entity: ntriangleright without a semi-colon",
- "output": [
- [
- "Character",
- "&ntriangleright"
- ]
- ]
- },
- {
- "input": "⋫",
- "description": "Named entity: ntriangleright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22eb"
- ]
- ]
- },
- {
- "input": "&ntrianglerighteq",
- "description": "Bad named entity: ntrianglerighteq without a semi-colon",
- "output": [
- [
- "Character",
- "&ntrianglerighteq"
- ]
- ]
- },
- {
- "input": "⋭",
- "description": "Named entity: ntrianglerighteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ed"
- ]
- ]
- },
- {
- "input": "&nu",
- "description": "Bad named entity: nu without a semi-colon",
- "output": [
- [
- "Character",
- "&nu"
- ]
- ]
- },
- {
- "input": "ν",
- "description": "Named entity: nu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03bd"
- ]
- ]
- },
- {
- "input": "&num",
- "description": "Bad named entity: num without a semi-colon",
- "output": [
- [
- "Character",
- "&num"
- ]
- ]
- },
- {
- "input": "#",
- "description": "Named entity: num; with a semi-colon",
- "output": [
- [
- "Character",
- "#"
- ]
- ]
- },
- {
- "input": "&numero",
- "description": "Bad named entity: numero without a semi-colon",
- "output": [
- [
- "Character",
- "&numero"
- ]
- ]
- },
- {
- "input": "№",
- "description": "Named entity: numero; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2116"
- ]
- ]
- },
- {
- "input": "&numsp",
- "description": "Bad named entity: numsp without a semi-colon",
- "output": [
- [
- "Character",
- "&numsp"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: numsp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2007"
- ]
- ]
- },
- {
- "input": "&nvDash",
- "description": "Bad named entity: nvDash without a semi-colon",
- "output": [
- [
- "Character",
- "&nvDash"
- ]
- ]
- },
- {
- "input": "⊭",
- "description": "Named entity: nvDash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ad"
- ]
- ]
- },
- {
- "input": "&nvHarr",
- "description": "Bad named entity: nvHarr without a semi-colon",
- "output": [
- [
- "Character",
- "&nvHarr"
- ]
- ]
- },
- {
- "input": "⤄",
- "description": "Named entity: nvHarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2904"
- ]
- ]
- },
- {
- "input": "&nvap",
- "description": "Bad named entity: nvap without a semi-colon",
- "output": [
- [
- "Character",
- "&nvap"
- ]
- ]
- },
- {
- "input": "≍⃒",
- "description": "Named entity: nvap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u224d\u20d2"
- ]
- ]
- },
- {
- "input": "&nvdash",
- "description": "Bad named entity: nvdash without a semi-colon",
- "output": [
- [
- "Character",
- "&nvdash"
- ]
- ]
- },
- {
- "input": "⊬",
- "description": "Named entity: nvdash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ac"
- ]
- ]
- },
- {
- "input": "&nvge",
- "description": "Bad named entity: nvge without a semi-colon",
- "output": [
- [
- "Character",
- "&nvge"
- ]
- ]
- },
- {
- "input": "≥⃒",
- "description": "Named entity: nvge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2265\u20d2"
- ]
- ]
- },
- {
- "input": "&nvgt",
- "description": "Bad named entity: nvgt without a semi-colon",
- "output": [
- [
- "Character",
- "&nvgt"
- ]
- ]
- },
- {
- "input": ">⃒",
- "description": "Named entity: nvgt; with a semi-colon",
- "output": [
- [
- "Character",
- ">\u20d2"
- ]
- ]
- },
- {
- "input": "&nvinfin",
- "description": "Bad named entity: nvinfin without a semi-colon",
- "output": [
- [
- "Character",
- "&nvinfin"
- ]
- ]
- },
- {
- "input": "⧞",
- "description": "Named entity: nvinfin; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29de"
- ]
- ]
- },
- {
- "input": "&nvlArr",
- "description": "Bad named entity: nvlArr without a semi-colon",
- "output": [
- [
- "Character",
- "&nvlArr"
- ]
- ]
- },
- {
- "input": "⤂",
- "description": "Named entity: nvlArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2902"
- ]
- ]
- },
- {
- "input": "&nvle",
- "description": "Bad named entity: nvle without a semi-colon",
- "output": [
- [
- "Character",
- "&nvle"
- ]
- ]
- },
- {
- "input": "≤⃒",
- "description": "Named entity: nvle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2264\u20d2"
- ]
- ]
- },
- {
- "input": "&nvlt",
- "description": "Bad named entity: nvlt without a semi-colon",
- "output": [
- [
- "Character",
- "&nvlt"
- ]
- ]
- },
- {
- "input": "<⃒",
- "description": "Named entity: nvlt; with a semi-colon",
- "output": [
- [
- "Character",
- "<\u20d2"
- ]
- ]
- },
- {
- "input": "&nvltrie",
- "description": "Bad named entity: nvltrie without a semi-colon",
- "output": [
- [
- "Character",
- "&nvltrie"
- ]
- ]
- },
- {
- "input": "⊴⃒",
- "description": "Named entity: nvltrie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b4\u20d2"
- ]
- ]
- },
- {
- "input": "&nvrArr",
- "description": "Bad named entity: nvrArr without a semi-colon",
- "output": [
- [
- "Character",
- "&nvrArr"
- ]
- ]
- },
- {
- "input": "⤃",
- "description": "Named entity: nvrArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2903"
- ]
- ]
- },
- {
- "input": "&nvrtrie",
- "description": "Bad named entity: nvrtrie without a semi-colon",
- "output": [
- [
- "Character",
- "&nvrtrie"
- ]
- ]
- },
- {
- "input": "⊵⃒",
- "description": "Named entity: nvrtrie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b5\u20d2"
- ]
- ]
- },
- {
- "input": "&nvsim",
- "description": "Bad named entity: nvsim without a semi-colon",
- "output": [
- [
- "Character",
- "&nvsim"
- ]
- ]
- },
- {
- "input": "∼⃒",
- "description": "Named entity: nvsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223c\u20d2"
- ]
- ]
- },
- {
- "input": "&nwArr",
- "description": "Bad named entity: nwArr without a semi-colon",
- "output": [
- [
- "Character",
- "&nwArr"
- ]
- ]
- },
- {
- "input": "⇖",
- "description": "Named entity: nwArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d6"
- ]
- ]
- },
- {
- "input": "&nwarhk",
- "description": "Bad named entity: nwarhk without a semi-colon",
- "output": [
- [
- "Character",
- "&nwarhk"
- ]
- ]
- },
- {
- "input": "⤣",
- "description": "Named entity: nwarhk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2923"
- ]
- ]
- },
- {
- "input": "&nwarr",
- "description": "Bad named entity: nwarr without a semi-colon",
- "output": [
- [
- "Character",
- "&nwarr"
- ]
- ]
- },
- {
- "input": "↖",
- "description": "Named entity: nwarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2196"
- ]
- ]
- },
- {
- "input": "&nwarrow",
- "description": "Bad named entity: nwarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&nwarrow"
- ]
- ]
- },
- {
- "input": "↖",
- "description": "Named entity: nwarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2196"
- ]
- ]
- },
- {
- "input": "&nwnear",
- "description": "Bad named entity: nwnear without a semi-colon",
- "output": [
- [
- "Character",
- "&nwnear"
- ]
- ]
- },
- {
- "input": "⤧",
- "description": "Named entity: nwnear; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2927"
- ]
- ]
- },
- {
- "input": "&oS",
- "description": "Bad named entity: oS without a semi-colon",
- "output": [
- [
- "Character",
- "&oS"
- ]
- ]
- },
- {
- "input": "Ⓢ",
- "description": "Named entity: oS; with a semi-colon",
- "output": [
- [
- "Character",
- "\u24c8"
- ]
- ]
- },
- {
- "input": "ó",
- "description": "Named entity: oacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f3"
- ]
- ]
- },
- {
- "input": "ó",
- "description": "Named entity: oacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f3"
- ]
- ]
- },
- {
- "input": "&oast",
- "description": "Bad named entity: oast without a semi-colon",
- "output": [
- [
- "Character",
- "&oast"
- ]
- ]
- },
- {
- "input": "⊛",
- "description": "Named entity: oast; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229b"
- ]
- ]
- },
- {
- "input": "&ocir",
- "description": "Bad named entity: ocir without a semi-colon",
- "output": [
- [
- "Character",
- "&ocir"
- ]
- ]
- },
- {
- "input": "⊚",
- "description": "Named entity: ocir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229a"
- ]
- ]
- },
- {
- "input": "ô",
- "description": "Named entity: ocirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f4"
- ]
- ]
- },
- {
- "input": "ô",
- "description": "Named entity: ocirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f4"
- ]
- ]
- },
- {
- "input": "&ocy",
- "description": "Bad named entity: ocy without a semi-colon",
- "output": [
- [
- "Character",
- "&ocy"
- ]
- ]
- },
- {
- "input": "о",
- "description": "Named entity: ocy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u043e"
- ]
- ]
- },
- {
- "input": "&odash",
- "description": "Bad named entity: odash without a semi-colon",
- "output": [
- [
- "Character",
- "&odash"
- ]
- ]
- },
- {
- "input": "⊝",
- "description": "Named entity: odash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229d"
- ]
- ]
- },
- {
- "input": "&odblac",
- "description": "Bad named entity: odblac without a semi-colon",
- "output": [
- [
- "Character",
- "&odblac"
- ]
- ]
- },
- {
- "input": "ő",
- "description": "Named entity: odblac; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0151"
- ]
- ]
- },
- {
- "input": "&odiv",
- "description": "Bad named entity: odiv without a semi-colon",
- "output": [
- [
- "Character",
- "&odiv"
- ]
- ]
- },
- {
- "input": "⨸",
- "description": "Named entity: odiv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a38"
- ]
- ]
- },
- {
- "input": "&odot",
- "description": "Bad named entity: odot without a semi-colon",
- "output": [
- [
- "Character",
- "&odot"
- ]
- ]
- },
- {
- "input": "⊙",
- "description": "Named entity: odot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2299"
- ]
- ]
- },
- {
- "input": "&odsold",
- "description": "Bad named entity: odsold without a semi-colon",
- "output": [
- [
- "Character",
- "&odsold"
- ]
- ]
- },
- {
- "input": "⦼",
- "description": "Named entity: odsold; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29bc"
- ]
- ]
- },
- {
- "input": "&oelig",
- "description": "Bad named entity: oelig without a semi-colon",
- "output": [
- [
- "Character",
- "&oelig"
- ]
- ]
- },
- {
- "input": "œ",
- "description": "Named entity: oelig; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0153"
- ]
- ]
- },
- {
- "input": "&ofcir",
- "description": "Bad named entity: ofcir without a semi-colon",
- "output": [
- [
- "Character",
- "&ofcir"
- ]
- ]
- },
- {
- "input": "⦿",
- "description": "Named entity: ofcir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29bf"
- ]
- ]
- },
- {
- "input": "&ofr",
- "description": "Bad named entity: ofr without a semi-colon",
- "output": [
- [
- "Character",
- "&ofr"
- ]
- ]
- },
- {
- "input": "𝔬",
- "description": "Named entity: ofr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd2c"
- ]
- ]
- },
- {
- "input": "&ogon",
- "description": "Bad named entity: ogon without a semi-colon",
- "output": [
- [
- "Character",
- "&ogon"
- ]
- ]
- },
- {
- "input": "˛",
- "description": "Named entity: ogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02db"
- ]
- ]
- },
- {
- "input": "ò",
- "description": "Named entity: ograve without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f2"
- ]
- ]
- },
- {
- "input": "ò",
- "description": "Named entity: ograve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f2"
- ]
- ]
- },
- {
- "input": "&ogt",
- "description": "Bad named entity: ogt without a semi-colon",
- "output": [
- [
- "Character",
- "&ogt"
- ]
- ]
- },
- {
- "input": "⧁",
- "description": "Named entity: ogt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29c1"
- ]
- ]
- },
- {
- "input": "&ohbar",
- "description": "Bad named entity: ohbar without a semi-colon",
- "output": [
- [
- "Character",
- "&ohbar"
- ]
- ]
- },
- {
- "input": "⦵",
- "description": "Named entity: ohbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b5"
- ]
- ]
- },
- {
- "input": "&ohm",
- "description": "Bad named entity: ohm without a semi-colon",
- "output": [
- [
- "Character",
- "&ohm"
- ]
- ]
- },
- {
- "input": "Ω",
- "description": "Named entity: ohm; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03a9"
- ]
- ]
- },
- {
- "input": "&oint",
- "description": "Bad named entity: oint without a semi-colon",
- "output": [
- [
- "Character",
- "&oint"
- ]
- ]
- },
- {
- "input": "∮",
- "description": "Named entity: oint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222e"
- ]
- ]
- },
- {
- "input": "&olarr",
- "description": "Bad named entity: olarr without a semi-colon",
- "output": [
- [
- "Character",
- "&olarr"
- ]
- ]
- },
- {
- "input": "↺",
- "description": "Named entity: olarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ba"
- ]
- ]
- },
- {
- "input": "&olcir",
- "description": "Bad named entity: olcir without a semi-colon",
- "output": [
- [
- "Character",
- "&olcir"
- ]
- ]
- },
- {
- "input": "⦾",
- "description": "Named entity: olcir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29be"
- ]
- ]
- },
- {
- "input": "&olcross",
- "description": "Bad named entity: olcross without a semi-colon",
- "output": [
- [
- "Character",
- "&olcross"
- ]
- ]
- },
- {
- "input": "⦻",
- "description": "Named entity: olcross; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29bb"
- ]
- ]
- },
- {
- "input": "&oline",
- "description": "Bad named entity: oline without a semi-colon",
- "output": [
- [
- "Character",
- "&oline"
- ]
- ]
- },
- {
- "input": "‾",
- "description": "Named entity: oline; with a semi-colon",
- "output": [
- [
- "Character",
- "\u203e"
- ]
- ]
- },
- {
- "input": "&olt",
- "description": "Bad named entity: olt without a semi-colon",
- "output": [
- [
- "Character",
- "&olt"
- ]
- ]
- },
- {
- "input": "⧀",
- "description": "Named entity: olt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29c0"
- ]
- ]
- },
- {
- "input": "&omacr",
- "description": "Bad named entity: omacr without a semi-colon",
- "output": [
- [
- "Character",
- "&omacr"
- ]
- ]
- },
- {
- "input": "ō",
- "description": "Named entity: omacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u014d"
- ]
- ]
- },
- {
- "input": "&omega",
- "description": "Bad named entity: omega without a semi-colon",
- "output": [
- [
- "Character",
- "&omega"
- ]
- ]
- },
- {
- "input": "ω",
- "description": "Named entity: omega; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c9"
- ]
- ]
- },
- {
- "input": "&omicron",
- "description": "Bad named entity: omicron without a semi-colon",
- "output": [
- [
- "Character",
- "&omicron"
- ]
- ]
- },
- {
- "input": "ο",
- "description": "Named entity: omicron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03bf"
- ]
- ]
- },
- {
- "input": "&omid",
- "description": "Bad named entity: omid without a semi-colon",
- "output": [
- [
- "Character",
- "&omid"
- ]
- ]
- },
- {
- "input": "⦶",
- "description": "Named entity: omid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b6"
- ]
- ]
- },
- {
- "input": "&ominus",
- "description": "Bad named entity: ominus without a semi-colon",
- "output": [
- [
- "Character",
- "&ominus"
- ]
- ]
- },
- {
- "input": "⊖",
- "description": "Named entity: ominus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2296"
- ]
- ]
- },
- {
- "input": "&oopf",
- "description": "Bad named entity: oopf without a semi-colon",
- "output": [
- [
- "Character",
- "&oopf"
- ]
- ]
- },
- {
- "input": "𝕠",
- "description": "Named entity: oopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd60"
- ]
- ]
- },
- {
- "input": "&opar",
- "description": "Bad named entity: opar without a semi-colon",
- "output": [
- [
- "Character",
- "&opar"
- ]
- ]
- },
- {
- "input": "⦷",
- "description": "Named entity: opar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b7"
- ]
- ]
- },
- {
- "input": "&operp",
- "description": "Bad named entity: operp without a semi-colon",
- "output": [
- [
- "Character",
- "&operp"
- ]
- ]
- },
- {
- "input": "⦹",
- "description": "Named entity: operp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b9"
- ]
- ]
- },
- {
- "input": "&oplus",
- "description": "Bad named entity: oplus without a semi-colon",
- "output": [
- [
- "Character",
- "&oplus"
- ]
- ]
- },
- {
- "input": "⊕",
- "description": "Named entity: oplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2295"
- ]
- ]
- },
- {
- "input": "&or",
- "description": "Bad named entity: or without a semi-colon",
- "output": [
- [
- "Character",
- "&or"
- ]
- ]
- },
- {
- "input": "∨",
- "description": "Named entity: or; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2228"
- ]
- ]
- },
- {
- "input": "&orarr",
- "description": "Bad named entity: orarr without a semi-colon",
- "output": [
- [
- "Character",
- "&orarr"
- ]
- ]
- },
- {
- "input": "↻",
- "description": "Named entity: orarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bb"
- ]
- ]
- },
- {
- "input": "&ord",
- "description": "Bad named entity: ord without a semi-colon",
- "output": [
- [
- "Character",
- "&ord"
- ]
- ]
- },
- {
- "input": "⩝",
- "description": "Named entity: ord; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a5d"
- ]
- ]
- },
- {
- "input": "&order",
- "description": "Bad named entity: order without a semi-colon",
- "output": [
- [
- "Character",
- "&order"
- ]
- ]
- },
- {
- "input": "ℴ",
- "description": "Named entity: order; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2134"
- ]
- ]
- },
- {
- "input": "&orderof",
- "description": "Bad named entity: orderof without a semi-colon",
- "output": [
- [
- "Character",
- "&orderof"
- ]
- ]
- },
- {
- "input": "ℴ",
- "description": "Named entity: orderof; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2134"
- ]
- ]
- },
- {
- "input": "ª",
- "description": "Named entity: ordf without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00aa"
- ]
- ]
- },
- {
- "input": "ª",
- "description": "Named entity: ordf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00aa"
- ]
- ]
- },
- {
- "input": "º",
- "description": "Named entity: ordm without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ba"
- ]
- ]
- },
- {
- "input": "º",
- "description": "Named entity: ordm; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ba"
- ]
- ]
- },
- {
- "input": "&origof",
- "description": "Bad named entity: origof without a semi-colon",
- "output": [
- [
- "Character",
- "&origof"
- ]
- ]
- },
- {
- "input": "⊶",
- "description": "Named entity: origof; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b6"
- ]
- ]
- },
- {
- "input": "&oror",
- "description": "Bad named entity: oror without a semi-colon",
- "output": [
- [
- "Character",
- "&oror"
- ]
- ]
- },
- {
- "input": "⩖",
- "description": "Named entity: oror; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a56"
- ]
- ]
- },
- {
- "input": "&orslope",
- "description": "Bad named entity: orslope without a semi-colon",
- "output": [
- [
- "Character",
- "&orslope"
- ]
- ]
- },
- {
- "input": "⩗",
- "description": "Named entity: orslope; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a57"
- ]
- ]
- },
- {
- "input": "&orv",
- "description": "Bad named entity: orv without a semi-colon",
- "output": [
- [
- "Character",
- "&orv"
- ]
- ]
- },
- {
- "input": "⩛",
- "description": "Named entity: orv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a5b"
- ]
- ]
- },
- {
- "input": "&oscr",
- "description": "Bad named entity: oscr without a semi-colon",
- "output": [
- [
- "Character",
- "&oscr"
- ]
- ]
- },
- {
- "input": "ℴ",
- "description": "Named entity: oscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2134"
- ]
- ]
- },
- {
- "input": "ø",
- "description": "Named entity: oslash without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f8"
- ]
- ]
- },
- {
- "input": "ø",
- "description": "Named entity: oslash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f8"
- ]
- ]
- },
- {
- "input": "&osol",
- "description": "Bad named entity: osol without a semi-colon",
- "output": [
- [
- "Character",
- "&osol"
- ]
- ]
- },
- {
- "input": "⊘",
- "description": "Named entity: osol; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2298"
- ]
- ]
- },
- {
- "input": "õ",
- "description": "Named entity: otilde without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f5"
- ]
- ]
- },
- {
- "input": "õ",
- "description": "Named entity: otilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f5"
- ]
- ]
- },
- {
- "input": "&otimes",
- "description": "Bad named entity: otimes without a semi-colon",
- "output": [
- [
- "Character",
- "&otimes"
- ]
- ]
- },
- {
- "input": "⊗",
- "description": "Named entity: otimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2297"
- ]
- ]
- },
- {
- "input": "&otimesas",
- "description": "Bad named entity: otimesas without a semi-colon",
- "output": [
- [
- "Character",
- "&otimesas"
- ]
- ]
- },
- {
- "input": "⨶",
- "description": "Named entity: otimesas; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a36"
- ]
- ]
- },
- {
- "input": "ö",
- "description": "Named entity: ouml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f6"
- ]
- ]
- },
- {
- "input": "ö",
- "description": "Named entity: ouml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f6"
- ]
- ]
- },
- {
- "input": "&ovbar",
- "description": "Bad named entity: ovbar without a semi-colon",
- "output": [
- [
- "Character",
- "&ovbar"
- ]
- ]
- },
- {
- "input": "⌽",
- "description": "Named entity: ovbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u233d"
- ]
- ]
- },
- {
- "input": "&par",
- "description": "Bad named entity: par without a semi-colon",
- "output": [
- [
- "Character",
- "&par"
- ]
- ]
- },
- {
- "input": "∥",
- "description": "Named entity: par; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2225"
- ]
- ]
- },
- {
- "input": "¶",
- "description": "Named entity: para without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b6"
- ]
- ]
- },
- {
- "input": "¶",
- "description": "Named entity: para; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b6"
- ]
- ]
- },
- {
- "input": "∥",
- "description": "Named entity: parallel; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2225"
- ]
- ]
- },
- {
- "input": "&parsim",
- "description": "Bad named entity: parsim without a semi-colon",
- "output": [
- [
- "Character",
- "&parsim"
- ]
- ]
- },
- {
- "input": "⫳",
- "description": "Named entity: parsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2af3"
- ]
- ]
- },
- {
- "input": "&parsl",
- "description": "Bad named entity: parsl without a semi-colon",
- "output": [
- [
- "Character",
- "&parsl"
- ]
- ]
- },
- {
- "input": "⫽",
- "description": "Named entity: parsl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2afd"
- ]
- ]
- },
- {
- "input": "&part",
- "description": "Bad named entity: part without a semi-colon",
- "output": [
- [
- "Character",
- "&part"
- ]
- ]
- },
- {
- "input": "∂",
- "description": "Named entity: part; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2202"
- ]
- ]
- },
- {
- "input": "&pcy",
- "description": "Bad named entity: pcy without a semi-colon",
- "output": [
- [
- "Character",
- "&pcy"
- ]
- ]
- },
- {
- "input": "п",
- "description": "Named entity: pcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u043f"
- ]
- ]
- },
- {
- "input": "&percnt",
- "description": "Bad named entity: percnt without a semi-colon",
- "output": [
- [
- "Character",
- "&percnt"
- ]
- ]
- },
- {
- "input": "%",
- "description": "Named entity: percnt; with a semi-colon",
- "output": [
- [
- "Character",
- "%"
- ]
- ]
- },
- {
- "input": "&period",
- "description": "Bad named entity: period without a semi-colon",
- "output": [
- [
- "Character",
- "&period"
- ]
- ]
- },
- {
- "input": ".",
- "description": "Named entity: period; with a semi-colon",
- "output": [
- [
- "Character",
- "."
- ]
- ]
- },
- {
- "input": "&permil",
- "description": "Bad named entity: permil without a semi-colon",
- "output": [
- [
- "Character",
- "&permil"
- ]
- ]
- },
- {
- "input": "‰",
- "description": "Named entity: permil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2030"
- ]
- ]
- },
- {
- "input": "&perp",
- "description": "Bad named entity: perp without a semi-colon",
- "output": [
- [
- "Character",
- "&perp"
- ]
- ]
- },
- {
- "input": "⊥",
- "description": "Named entity: perp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a5"
- ]
- ]
- },
- {
- "input": "&pertenk",
- "description": "Bad named entity: pertenk without a semi-colon",
- "output": [
- [
- "Character",
- "&pertenk"
- ]
- ]
- },
- {
- "input": "‱",
- "description": "Named entity: pertenk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2031"
- ]
- ]
- },
- {
- "input": "&pfr",
- "description": "Bad named entity: pfr without a semi-colon",
- "output": [
- [
- "Character",
- "&pfr"
- ]
- ]
- },
- {
- "input": "𝔭",
- "description": "Named entity: pfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd2d"
- ]
- ]
- },
- {
- "input": "&phi",
- "description": "Bad named entity: phi without a semi-colon",
- "output": [
- [
- "Character",
- "&phi"
- ]
- ]
- },
- {
- "input": "φ",
- "description": "Named entity: phi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c6"
- ]
- ]
- },
- {
- "input": "&phiv",
- "description": "Bad named entity: phiv without a semi-colon",
- "output": [
- [
- "Character",
- "&phiv"
- ]
- ]
- },
- {
- "input": "ϕ",
- "description": "Named entity: phiv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d5"
- ]
- ]
- },
- {
- "input": "&phmmat",
- "description": "Bad named entity: phmmat without a semi-colon",
- "output": [
- [
- "Character",
- "&phmmat"
- ]
- ]
- },
- {
- "input": "ℳ",
- "description": "Named entity: phmmat; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2133"
- ]
- ]
- },
- {
- "input": "&phone",
- "description": "Bad named entity: phone without a semi-colon",
- "output": [
- [
- "Character",
- "&phone"
- ]
- ]
- },
- {
- "input": "☎",
- "description": "Named entity: phone; with a semi-colon",
- "output": [
- [
- "Character",
- "\u260e"
- ]
- ]
- },
- {
- "input": "&pi",
- "description": "Bad named entity: pi without a semi-colon",
- "output": [
- [
- "Character",
- "&pi"
- ]
- ]
- },
- {
- "input": "π",
- "description": "Named entity: pi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c0"
- ]
- ]
- },
- {
- "input": "&pitchfork",
- "description": "Bad named entity: pitchfork without a semi-colon",
- "output": [
- [
- "Character",
- "&pitchfork"
- ]
- ]
- },
- {
- "input": "⋔",
- "description": "Named entity: pitchfork; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22d4"
- ]
- ]
- },
- {
- "input": "&piv",
- "description": "Bad named entity: piv without a semi-colon",
- "output": [
- [
- "Character",
- "&piv"
- ]
- ]
- },
- {
- "input": "ϖ",
- "description": "Named entity: piv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d6"
- ]
- ]
- },
- {
- "input": "&planck",
- "description": "Bad named entity: planck without a semi-colon",
- "output": [
- [
- "Character",
- "&planck"
- ]
- ]
- },
- {
- "input": "ℏ",
- "description": "Named entity: planck; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210f"
- ]
- ]
- },
- {
- "input": "&planckh",
- "description": "Bad named entity: planckh without a semi-colon",
- "output": [
- [
- "Character",
- "&planckh"
- ]
- ]
- },
- {
- "input": "ℎ",
- "description": "Named entity: planckh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210e"
- ]
- ]
- },
- {
- "input": "&plankv",
- "description": "Bad named entity: plankv without a semi-colon",
- "output": [
- [
- "Character",
- "&plankv"
- ]
- ]
- },
- {
- "input": "ℏ",
- "description": "Named entity: plankv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210f"
- ]
- ]
- },
- {
- "input": "&plus",
- "description": "Bad named entity: plus without a semi-colon",
- "output": [
- [
- "Character",
- "&plus"
- ]
- ]
- },
- {
- "input": "+",
- "description": "Named entity: plus; with a semi-colon",
- "output": [
- [
- "Character",
- "+"
- ]
- ]
- },
- {
- "input": "&plusacir",
- "description": "Bad named entity: plusacir without a semi-colon",
- "output": [
- [
- "Character",
- "&plusacir"
- ]
- ]
- },
- {
- "input": "⨣",
- "description": "Named entity: plusacir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a23"
- ]
- ]
- },
- {
- "input": "&plusb",
- "description": "Bad named entity: plusb without a semi-colon",
- "output": [
- [
- "Character",
- "&plusb"
- ]
- ]
- },
- {
- "input": "⊞",
- "description": "Named entity: plusb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u229e"
- ]
- ]
- },
- {
- "input": "&pluscir",
- "description": "Bad named entity: pluscir without a semi-colon",
- "output": [
- [
- "Character",
- "&pluscir"
- ]
- ]
- },
- {
- "input": "⨢",
- "description": "Named entity: pluscir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a22"
- ]
- ]
- },
- {
- "input": "&plusdo",
- "description": "Bad named entity: plusdo without a semi-colon",
- "output": [
- [
- "Character",
- "&plusdo"
- ]
- ]
- },
- {
- "input": "∔",
- "description": "Named entity: plusdo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2214"
- ]
- ]
- },
- {
- "input": "&plusdu",
- "description": "Bad named entity: plusdu without a semi-colon",
- "output": [
- [
- "Character",
- "&plusdu"
- ]
- ]
- },
- {
- "input": "⨥",
- "description": "Named entity: plusdu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a25"
- ]
- ]
- },
- {
- "input": "&pluse",
- "description": "Bad named entity: pluse without a semi-colon",
- "output": [
- [
- "Character",
- "&pluse"
- ]
- ]
- },
- {
- "input": "⩲",
- "description": "Named entity: pluse; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a72"
- ]
- ]
- },
- {
- "input": "±",
- "description": "Named entity: plusmn without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b1"
- ]
- ]
- },
- {
- "input": "±",
- "description": "Named entity: plusmn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b1"
- ]
- ]
- },
- {
- "input": "&plussim",
- "description": "Bad named entity: plussim without a semi-colon",
- "output": [
- [
- "Character",
- "&plussim"
- ]
- ]
- },
- {
- "input": "⨦",
- "description": "Named entity: plussim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a26"
- ]
- ]
- },
- {
- "input": "&plustwo",
- "description": "Bad named entity: plustwo without a semi-colon",
- "output": [
- [
- "Character",
- "&plustwo"
- ]
- ]
- },
- {
- "input": "⨧",
- "description": "Named entity: plustwo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a27"
- ]
- ]
- },
- {
- "input": "&pm",
- "description": "Bad named entity: pm without a semi-colon",
- "output": [
- [
- "Character",
- "&pm"
- ]
- ]
- },
- {
- "input": "±",
- "description": "Named entity: pm; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b1"
- ]
- ]
- },
- {
- "input": "&pointint",
- "description": "Bad named entity: pointint without a semi-colon",
- "output": [
- [
- "Character",
- "&pointint"
- ]
- ]
- },
- {
- "input": "⨕",
- "description": "Named entity: pointint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a15"
- ]
- ]
- },
- {
- "input": "&popf",
- "description": "Bad named entity: popf without a semi-colon",
- "output": [
- [
- "Character",
- "&popf"
- ]
- ]
- },
- {
- "input": "𝕡",
- "description": "Named entity: popf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd61"
- ]
- ]
- },
- {
- "input": "£",
- "description": "Named entity: pound without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a3"
- ]
- ]
- },
- {
- "input": "£",
- "description": "Named entity: pound; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a3"
- ]
- ]
- },
- {
- "input": "&pr",
- "description": "Bad named entity: pr without a semi-colon",
- "output": [
- [
- "Character",
- "&pr"
- ]
- ]
- },
- {
- "input": "≺",
- "description": "Named entity: pr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227a"
- ]
- ]
- },
- {
- "input": "&prE",
- "description": "Bad named entity: prE without a semi-colon",
- "output": [
- [
- "Character",
- "&prE"
- ]
- ]
- },
- {
- "input": "⪳",
- "description": "Named entity: prE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab3"
- ]
- ]
- },
- {
- "input": "&prap",
- "description": "Bad named entity: prap without a semi-colon",
- "output": [
- [
- "Character",
- "&prap"
- ]
- ]
- },
- {
- "input": "⪷",
- "description": "Named entity: prap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab7"
- ]
- ]
- },
- {
- "input": "&prcue",
- "description": "Bad named entity: prcue without a semi-colon",
- "output": [
- [
- "Character",
- "&prcue"
- ]
- ]
- },
- {
- "input": "≼",
- "description": "Named entity: prcue; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227c"
- ]
- ]
- },
- {
- "input": "&pre",
- "description": "Bad named entity: pre without a semi-colon",
- "output": [
- [
- "Character",
- "&pre"
- ]
- ]
- },
- {
- "input": "⪯",
- "description": "Named entity: pre; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aaf"
- ]
- ]
- },
- {
- "input": "&prec",
- "description": "Bad named entity: prec without a semi-colon",
- "output": [
- [
- "Character",
- "&prec"
- ]
- ]
- },
- {
- "input": "≺",
- "description": "Named entity: prec; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227a"
- ]
- ]
- },
- {
- "input": "&precapprox",
- "description": "Bad named entity: precapprox without a semi-colon",
- "output": [
- [
- "Character",
- "&precapprox"
- ]
- ]
- },
- {
- "input": "⪷",
- "description": "Named entity: precapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab7"
- ]
- ]
- },
- {
- "input": "&preccurlyeq",
- "description": "Bad named entity: preccurlyeq without a semi-colon",
- "output": [
- [
- "Character",
- "&preccurlyeq"
- ]
- ]
- },
- {
- "input": "≼",
- "description": "Named entity: preccurlyeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227c"
- ]
- ]
- },
- {
- "input": "&preceq",
- "description": "Bad named entity: preceq without a semi-colon",
- "output": [
- [
- "Character",
- "&preceq"
- ]
- ]
- },
- {
- "input": "⪯",
- "description": "Named entity: preceq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aaf"
- ]
- ]
- },
- {
- "input": "&precnapprox",
- "description": "Bad named entity: precnapprox without a semi-colon",
- "output": [
- [
- "Character",
- "&precnapprox"
- ]
- ]
- },
- {
- "input": "⪹",
- "description": "Named entity: precnapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab9"
- ]
- ]
- },
- {
- "input": "&precneqq",
- "description": "Bad named entity: precneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&precneqq"
- ]
- ]
- },
- {
- "input": "⪵",
- "description": "Named entity: precneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab5"
- ]
- ]
- },
- {
- "input": "&precnsim",
- "description": "Bad named entity: precnsim without a semi-colon",
- "output": [
- [
- "Character",
- "&precnsim"
- ]
- ]
- },
- {
- "input": "⋨",
- "description": "Named entity: precnsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e8"
- ]
- ]
- },
- {
- "input": "&precsim",
- "description": "Bad named entity: precsim without a semi-colon",
- "output": [
- [
- "Character",
- "&precsim"
- ]
- ]
- },
- {
- "input": "≾",
- "description": "Named entity: precsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227e"
- ]
- ]
- },
- {
- "input": "&prime",
- "description": "Bad named entity: prime without a semi-colon",
- "output": [
- [
- "Character",
- "&prime"
- ]
- ]
- },
- {
- "input": "′",
- "description": "Named entity: prime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2032"
- ]
- ]
- },
- {
- "input": "&primes",
- "description": "Bad named entity: primes without a semi-colon",
- "output": [
- [
- "Character",
- "&primes"
- ]
- ]
- },
- {
- "input": "ℙ",
- "description": "Named entity: primes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2119"
- ]
- ]
- },
- {
- "input": "&prnE",
- "description": "Bad named entity: prnE without a semi-colon",
- "output": [
- [
- "Character",
- "&prnE"
- ]
- ]
- },
- {
- "input": "⪵",
- "description": "Named entity: prnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab5"
- ]
- ]
- },
- {
- "input": "&prnap",
- "description": "Bad named entity: prnap without a semi-colon",
- "output": [
- [
- "Character",
- "&prnap"
- ]
- ]
- },
- {
- "input": "⪹",
- "description": "Named entity: prnap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab9"
- ]
- ]
- },
- {
- "input": "&prnsim",
- "description": "Bad named entity: prnsim without a semi-colon",
- "output": [
- [
- "Character",
- "&prnsim"
- ]
- ]
- },
- {
- "input": "⋨",
- "description": "Named entity: prnsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e8"
- ]
- ]
- },
- {
- "input": "&prod",
- "description": "Bad named entity: prod without a semi-colon",
- "output": [
- [
- "Character",
- "&prod"
- ]
- ]
- },
- {
- "input": "∏",
- "description": "Named entity: prod; with a semi-colon",
- "output": [
- [
- "Character",
- "\u220f"
- ]
- ]
- },
- {
- "input": "&profalar",
- "description": "Bad named entity: profalar without a semi-colon",
- "output": [
- [
- "Character",
- "&profalar"
- ]
- ]
- },
- {
- "input": "⌮",
- "description": "Named entity: profalar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u232e"
- ]
- ]
- },
- {
- "input": "&profline",
- "description": "Bad named entity: profline without a semi-colon",
- "output": [
- [
- "Character",
- "&profline"
- ]
- ]
- },
- {
- "input": "⌒",
- "description": "Named entity: profline; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2312"
- ]
- ]
- },
- {
- "input": "&profsurf",
- "description": "Bad named entity: profsurf without a semi-colon",
- "output": [
- [
- "Character",
- "&profsurf"
- ]
- ]
- },
- {
- "input": "⌓",
- "description": "Named entity: profsurf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2313"
- ]
- ]
- },
- {
- "input": "&prop",
- "description": "Bad named entity: prop without a semi-colon",
- "output": [
- [
- "Character",
- "&prop"
- ]
- ]
- },
- {
- "input": "∝",
- "description": "Named entity: prop; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221d"
- ]
- ]
- },
- {
- "input": "&propto",
- "description": "Bad named entity: propto without a semi-colon",
- "output": [
- [
- "Character",
- "&propto"
- ]
- ]
- },
- {
- "input": "∝",
- "description": "Named entity: propto; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221d"
- ]
- ]
- },
- {
- "input": "&prsim",
- "description": "Bad named entity: prsim without a semi-colon",
- "output": [
- [
- "Character",
- "&prsim"
- ]
- ]
- },
- {
- "input": "≾",
- "description": "Named entity: prsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227e"
- ]
- ]
- },
- {
- "input": "&prurel",
- "description": "Bad named entity: prurel without a semi-colon",
- "output": [
- [
- "Character",
- "&prurel"
- ]
- ]
- },
- {
- "input": "⊰",
- "description": "Named entity: prurel; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b0"
- ]
- ]
- },
- {
- "input": "&pscr",
- "description": "Bad named entity: pscr without a semi-colon",
- "output": [
- [
- "Character",
- "&pscr"
- ]
- ]
- },
- {
- "input": "𝓅",
- "description": "Named entity: pscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc5"
- ]
- ]
- },
- {
- "input": "&psi",
- "description": "Bad named entity: psi without a semi-colon",
- "output": [
- [
- "Character",
- "&psi"
- ]
- ]
- },
- {
- "input": "ψ",
- "description": "Named entity: psi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c8"
- ]
- ]
- },
- {
- "input": "&puncsp",
- "description": "Bad named entity: puncsp without a semi-colon",
- "output": [
- [
- "Character",
- "&puncsp"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: puncsp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2008"
- ]
- ]
- },
- {
- "input": "&qfr",
- "description": "Bad named entity: qfr without a semi-colon",
- "output": [
- [
- "Character",
- "&qfr"
- ]
- ]
- },
- {
- "input": "𝔮",
- "description": "Named entity: qfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd2e"
- ]
- ]
- },
- {
- "input": "&qint",
- "description": "Bad named entity: qint without a semi-colon",
- "output": [
- [
- "Character",
- "&qint"
- ]
- ]
- },
- {
- "input": "⨌",
- "description": "Named entity: qint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a0c"
- ]
- ]
- },
- {
- "input": "&qopf",
- "description": "Bad named entity: qopf without a semi-colon",
- "output": [
- [
- "Character",
- "&qopf"
- ]
- ]
- },
- {
- "input": "𝕢",
- "description": "Named entity: qopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd62"
- ]
- ]
- },
- {
- "input": "&qprime",
- "description": "Bad named entity: qprime without a semi-colon",
- "output": [
- [
- "Character",
- "&qprime"
- ]
- ]
- },
- {
- "input": "⁗",
- "description": "Named entity: qprime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2057"
- ]
- ]
- },
- {
- "input": "&qscr",
- "description": "Bad named entity: qscr without a semi-colon",
- "output": [
- [
- "Character",
- "&qscr"
- ]
- ]
- },
- {
- "input": "𝓆",
- "description": "Named entity: qscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc6"
- ]
- ]
- },
- {
- "input": "&quaternions",
- "description": "Bad named entity: quaternions without a semi-colon",
- "output": [
- [
- "Character",
- "&quaternions"
- ]
- ]
- },
- {
- "input": "ℍ",
- "description": "Named entity: quaternions; with a semi-colon",
- "output": [
- [
- "Character",
- "\u210d"
- ]
- ]
- },
- {
- "input": "&quatint",
- "description": "Bad named entity: quatint without a semi-colon",
- "output": [
- [
- "Character",
- "&quatint"
- ]
- ]
- },
- {
- "input": "⨖",
- "description": "Named entity: quatint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a16"
- ]
- ]
- },
- {
- "input": "&quest",
- "description": "Bad named entity: quest without a semi-colon",
- "output": [
- [
- "Character",
- "&quest"
- ]
- ]
- },
- {
- "input": "?",
- "description": "Named entity: quest; with a semi-colon",
- "output": [
- [
- "Character",
- "?"
- ]
- ]
- },
- {
- "input": "&questeq",
- "description": "Bad named entity: questeq without a semi-colon",
- "output": [
- [
- "Character",
- "&questeq"
- ]
- ]
- },
- {
- "input": "≟",
- "description": "Named entity: questeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u225f"
- ]
- ]
- },
- {
- "input": """,
- "description": "Named entity: quot without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\""
- ]
- ]
- },
- {
- "input": """,
- "description": "Named entity: quot; with a semi-colon",
- "output": [
- [
- "Character",
- "\""
- ]
- ]
- },
- {
- "input": "&rAarr",
- "description": "Bad named entity: rAarr without a semi-colon",
- "output": [
- [
- "Character",
- "&rAarr"
- ]
- ]
- },
- {
- "input": "⇛",
- "description": "Named entity: rAarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21db"
- ]
- ]
- },
- {
- "input": "&rArr",
- "description": "Bad named entity: rArr without a semi-colon",
- "output": [
- [
- "Character",
- "&rArr"
- ]
- ]
- },
- {
- "input": "⇒",
- "description": "Named entity: rArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d2"
- ]
- ]
- },
- {
- "input": "&rAtail",
- "description": "Bad named entity: rAtail without a semi-colon",
- "output": [
- [
- "Character",
- "&rAtail"
- ]
- ]
- },
- {
- "input": "⤜",
- "description": "Named entity: rAtail; with a semi-colon",
- "output": [
- [
- "Character",
- "\u291c"
- ]
- ]
- },
- {
- "input": "&rBarr",
- "description": "Bad named entity: rBarr without a semi-colon",
- "output": [
- [
- "Character",
- "&rBarr"
- ]
- ]
- },
- {
- "input": "⤏",
- "description": "Named entity: rBarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u290f"
- ]
- ]
- },
- {
- "input": "&rHar",
- "description": "Bad named entity: rHar without a semi-colon",
- "output": [
- [
- "Character",
- "&rHar"
- ]
- ]
- },
- {
- "input": "⥤",
- "description": "Named entity: rHar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2964"
- ]
- ]
- },
- {
- "input": "&race",
- "description": "Bad named entity: race without a semi-colon",
- "output": [
- [
- "Character",
- "&race"
- ]
- ]
- },
- {
- "input": "∽̱",
- "description": "Named entity: race; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223d\u0331"
- ]
- ]
- },
- {
- "input": "&racute",
- "description": "Bad named entity: racute without a semi-colon",
- "output": [
- [
- "Character",
- "&racute"
- ]
- ]
- },
- {
- "input": "ŕ",
- "description": "Named entity: racute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0155"
- ]
- ]
- },
- {
- "input": "&radic",
- "description": "Bad named entity: radic without a semi-colon",
- "output": [
- [
- "Character",
- "&radic"
- ]
- ]
- },
- {
- "input": "√",
- "description": "Named entity: radic; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221a"
- ]
- ]
- },
- {
- "input": "&raemptyv",
- "description": "Bad named entity: raemptyv without a semi-colon",
- "output": [
- [
- "Character",
- "&raemptyv"
- ]
- ]
- },
- {
- "input": "⦳",
- "description": "Named entity: raemptyv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29b3"
- ]
- ]
- },
- {
- "input": "&rang",
- "description": "Bad named entity: rang without a semi-colon",
- "output": [
- [
- "Character",
- "&rang"
- ]
- ]
- },
- {
- "input": "〉",
- "description": "Named entity: rang; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e9"
- ]
- ]
- },
- {
- "input": "&rangd",
- "description": "Bad named entity: rangd without a semi-colon",
- "output": [
- [
- "Character",
- "&rangd"
- ]
- ]
- },
- {
- "input": "⦒",
- "description": "Named entity: rangd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2992"
- ]
- ]
- },
- {
- "input": "&range",
- "description": "Bad named entity: range without a semi-colon",
- "output": [
- [
- "Character",
- "&range"
- ]
- ]
- },
- {
- "input": "⦥",
- "description": "Named entity: range; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29a5"
- ]
- ]
- },
- {
- "input": "&rangle",
- "description": "Bad named entity: rangle without a semi-colon",
- "output": [
- [
- "Character",
- "&rangle"
- ]
- ]
- },
- {
- "input": "⟩",
- "description": "Named entity: rangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e9"
- ]
- ]
- },
- {
- "input": "»",
- "description": "Named entity: raquo without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00bb"
- ]
- ]
- },
- {
- "input": "»",
- "description": "Named entity: raquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00bb"
- ]
- ]
- },
- {
- "input": "&rarr",
- "description": "Bad named entity: rarr without a semi-colon",
- "output": [
- [
- "Character",
- "&rarr"
- ]
- ]
- },
- {
- "input": "→",
- "description": "Named entity: rarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2192"
- ]
- ]
- },
- {
- "input": "&rarrap",
- "description": "Bad named entity: rarrap without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrap"
- ]
- ]
- },
- {
- "input": "⥵",
- "description": "Named entity: rarrap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2975"
- ]
- ]
- },
- {
- "input": "&rarrb",
- "description": "Bad named entity: rarrb without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrb"
- ]
- ]
- },
- {
- "input": "⇥",
- "description": "Named entity: rarrb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21e5"
- ]
- ]
- },
- {
- "input": "&rarrbfs",
- "description": "Bad named entity: rarrbfs without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrbfs"
- ]
- ]
- },
- {
- "input": "⤠",
- "description": "Named entity: rarrbfs; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2920"
- ]
- ]
- },
- {
- "input": "&rarrc",
- "description": "Bad named entity: rarrc without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrc"
- ]
- ]
- },
- {
- "input": "⤳",
- "description": "Named entity: rarrc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2933"
- ]
- ]
- },
- {
- "input": "&rarrfs",
- "description": "Bad named entity: rarrfs without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrfs"
- ]
- ]
- },
- {
- "input": "⤞",
- "description": "Named entity: rarrfs; with a semi-colon",
- "output": [
- [
- "Character",
- "\u291e"
- ]
- ]
- },
- {
- "input": "&rarrhk",
- "description": "Bad named entity: rarrhk without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrhk"
- ]
- ]
- },
- {
- "input": "↪",
- "description": "Named entity: rarrhk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21aa"
- ]
- ]
- },
- {
- "input": "&rarrlp",
- "description": "Bad named entity: rarrlp without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrlp"
- ]
- ]
- },
- {
- "input": "↬",
- "description": "Named entity: rarrlp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21ac"
- ]
- ]
- },
- {
- "input": "&rarrpl",
- "description": "Bad named entity: rarrpl without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrpl"
- ]
- ]
- },
- {
- "input": "⥅",
- "description": "Named entity: rarrpl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2945"
- ]
- ]
- },
- {
- "input": "&rarrsim",
- "description": "Bad named entity: rarrsim without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrsim"
- ]
- ]
- },
- {
- "input": "⥴",
- "description": "Named entity: rarrsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2974"
- ]
- ]
- },
- {
- "input": "&rarrtl",
- "description": "Bad named entity: rarrtl without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrtl"
- ]
- ]
- },
- {
- "input": "↣",
- "description": "Named entity: rarrtl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a3"
- ]
- ]
- },
- {
- "input": "&rarrw",
- "description": "Bad named entity: rarrw without a semi-colon",
- "output": [
- [
- "Character",
- "&rarrw"
- ]
- ]
- },
- {
- "input": "↝",
- "description": "Named entity: rarrw; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219d"
- ]
- ]
- },
- {
- "input": "&ratail",
- "description": "Bad named entity: ratail without a semi-colon",
- "output": [
- [
- "Character",
- "&ratail"
- ]
- ]
- },
- {
- "input": "⤚",
- "description": "Named entity: ratail; with a semi-colon",
- "output": [
- [
- "Character",
- "\u291a"
- ]
- ]
- },
- {
- "input": "&ratio",
- "description": "Bad named entity: ratio without a semi-colon",
- "output": [
- [
- "Character",
- "&ratio"
- ]
- ]
- },
- {
- "input": "∶",
- "description": "Named entity: ratio; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2236"
- ]
- ]
- },
- {
- "input": "&rationals",
- "description": "Bad named entity: rationals without a semi-colon",
- "output": [
- [
- "Character",
- "&rationals"
- ]
- ]
- },
- {
- "input": "ℚ",
- "description": "Named entity: rationals; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211a"
- ]
- ]
- },
- {
- "input": "&rbarr",
- "description": "Bad named entity: rbarr without a semi-colon",
- "output": [
- [
- "Character",
- "&rbarr"
- ]
- ]
- },
- {
- "input": "⤍",
- "description": "Named entity: rbarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u290d"
- ]
- ]
- },
- {
- "input": "&rbbrk",
- "description": "Bad named entity: rbbrk without a semi-colon",
- "output": [
- [
- "Character",
- "&rbbrk"
- ]
- ]
- },
- {
- "input": "❳",
- "description": "Named entity: rbbrk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2773"
- ]
- ]
- },
- {
- "input": "&rbrace",
- "description": "Bad named entity: rbrace without a semi-colon",
- "output": [
- [
- "Character",
- "&rbrace"
- ]
- ]
- },
- {
- "input": "}",
- "description": "Named entity: rbrace; with a semi-colon",
- "output": [
- [
- "Character",
- "}"
- ]
- ]
- },
- {
- "input": "&rbrack",
- "description": "Bad named entity: rbrack without a semi-colon",
- "output": [
- [
- "Character",
- "&rbrack"
- ]
- ]
- },
- {
- "input": "]",
- "description": "Named entity: rbrack; with a semi-colon",
- "output": [
- [
- "Character",
- "]"
- ]
- ]
- },
- {
- "input": "&rbrke",
- "description": "Bad named entity: rbrke without a semi-colon",
- "output": [
- [
- "Character",
- "&rbrke"
- ]
- ]
- },
- {
- "input": "⦌",
- "description": "Named entity: rbrke; with a semi-colon",
- "output": [
- [
- "Character",
- "\u298c"
- ]
- ]
- },
- {
- "input": "&rbrksld",
- "description": "Bad named entity: rbrksld without a semi-colon",
- "output": [
- [
- "Character",
- "&rbrksld"
- ]
- ]
- },
- {
- "input": "⦎",
- "description": "Named entity: rbrksld; with a semi-colon",
- "output": [
- [
- "Character",
- "\u298e"
- ]
- ]
- },
- {
- "input": "&rbrkslu",
- "description": "Bad named entity: rbrkslu without a semi-colon",
- "output": [
- [
- "Character",
- "&rbrkslu"
- ]
- ]
- },
- {
- "input": "⦐",
- "description": "Named entity: rbrkslu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2990"
- ]
- ]
- },
- {
- "input": "&rcaron",
- "description": "Bad named entity: rcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&rcaron"
- ]
- ]
- },
- {
- "input": "ř",
- "description": "Named entity: rcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0159"
- ]
- ]
- },
- {
- "input": "&rcedil",
- "description": "Bad named entity: rcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&rcedil"
- ]
- ]
- },
- {
- "input": "ŗ",
- "description": "Named entity: rcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0157"
- ]
- ]
- },
- {
- "input": "&rceil",
- "description": "Bad named entity: rceil without a semi-colon",
- "output": [
- [
- "Character",
- "&rceil"
- ]
- ]
- },
- {
- "input": "⌉",
- "description": "Named entity: rceil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2309"
- ]
- ]
- },
- {
- "input": "&rcub",
- "description": "Bad named entity: rcub without a semi-colon",
- "output": [
- [
- "Character",
- "&rcub"
- ]
- ]
- },
- {
- "input": "}",
- "description": "Named entity: rcub; with a semi-colon",
- "output": [
- [
- "Character",
- "}"
- ]
- ]
- },
- {
- "input": "&rcy",
- "description": "Bad named entity: rcy without a semi-colon",
- "output": [
- [
- "Character",
- "&rcy"
- ]
- ]
- },
- {
- "input": "р",
- "description": "Named entity: rcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0440"
- ]
- ]
- },
- {
- "input": "&rdca",
- "description": "Bad named entity: rdca without a semi-colon",
- "output": [
- [
- "Character",
- "&rdca"
- ]
- ]
- },
- {
- "input": "⤷",
- "description": "Named entity: rdca; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2937"
- ]
- ]
- },
- {
- "input": "&rdldhar",
- "description": "Bad named entity: rdldhar without a semi-colon",
- "output": [
- [
- "Character",
- "&rdldhar"
- ]
- ]
- },
- {
- "input": "⥩",
- "description": "Named entity: rdldhar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2969"
- ]
- ]
- },
- {
- "input": "&rdquo",
- "description": "Bad named entity: rdquo without a semi-colon",
- "output": [
- [
- "Character",
- "&rdquo"
- ]
- ]
- },
- {
- "input": "”",
- "description": "Named entity: rdquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201d"
- ]
- ]
- },
- {
- "input": "&rdquor",
- "description": "Bad named entity: rdquor without a semi-colon",
- "output": [
- [
- "Character",
- "&rdquor"
- ]
- ]
- },
- {
- "input": "”",
- "description": "Named entity: rdquor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201d"
- ]
- ]
- },
- {
- "input": "&rdsh",
- "description": "Bad named entity: rdsh without a semi-colon",
- "output": [
- [
- "Character",
- "&rdsh"
- ]
- ]
- },
- {
- "input": "↳",
- "description": "Named entity: rdsh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b3"
- ]
- ]
- },
- {
- "input": "&real",
- "description": "Bad named entity: real without a semi-colon",
- "output": [
- [
- "Character",
- "&real"
- ]
- ]
- },
- {
- "input": "ℜ",
- "description": "Named entity: real; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211c"
- ]
- ]
- },
- {
- "input": "&realine",
- "description": "Bad named entity: realine without a semi-colon",
- "output": [
- [
- "Character",
- "&realine"
- ]
- ]
- },
- {
- "input": "ℛ",
- "description": "Named entity: realine; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211b"
- ]
- ]
- },
- {
- "input": "&realpart",
- "description": "Bad named entity: realpart without a semi-colon",
- "output": [
- [
- "Character",
- "&realpart"
- ]
- ]
- },
- {
- "input": "ℜ",
- "description": "Named entity: realpart; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211c"
- ]
- ]
- },
- {
- "input": "&reals",
- "description": "Bad named entity: reals without a semi-colon",
- "output": [
- [
- "Character",
- "&reals"
- ]
- ]
- },
- {
- "input": "ℝ",
- "description": "Named entity: reals; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211d"
- ]
- ]
- },
- {
- "input": "&rect",
- "description": "Bad named entity: rect without a semi-colon",
- "output": [
- [
- "Character",
- "&rect"
- ]
- ]
- },
- {
- "input": "▭",
- "description": "Named entity: rect; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25ad"
- ]
- ]
- },
- {
- "input": "®",
- "description": "Named entity: reg without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ae"
- ]
- ]
- },
- {
- "input": "®",
- "description": "Named entity: reg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ae"
- ]
- ]
- },
- {
- "input": "&rfisht",
- "description": "Bad named entity: rfisht without a semi-colon",
- "output": [
- [
- "Character",
- "&rfisht"
- ]
- ]
- },
- {
- "input": "⥽",
- "description": "Named entity: rfisht; with a semi-colon",
- "output": [
- [
- "Character",
- "\u297d"
- ]
- ]
- },
- {
- "input": "&rfloor",
- "description": "Bad named entity: rfloor without a semi-colon",
- "output": [
- [
- "Character",
- "&rfloor"
- ]
- ]
- },
- {
- "input": "⌋",
- "description": "Named entity: rfloor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u230b"
- ]
- ]
- },
- {
- "input": "&rfr",
- "description": "Bad named entity: rfr without a semi-colon",
- "output": [
- [
- "Character",
- "&rfr"
- ]
- ]
- },
- {
- "input": "𝔯",
- "description": "Named entity: rfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd2f"
- ]
- ]
- },
- {
- "input": "&rhard",
- "description": "Bad named entity: rhard without a semi-colon",
- "output": [
- [
- "Character",
- "&rhard"
- ]
- ]
- },
- {
- "input": "⇁",
- "description": "Named entity: rhard; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c1"
- ]
- ]
- },
- {
- "input": "&rharu",
- "description": "Bad named entity: rharu without a semi-colon",
- "output": [
- [
- "Character",
- "&rharu"
- ]
- ]
- },
- {
- "input": "⇀",
- "description": "Named entity: rharu; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c0"
- ]
- ]
- },
- {
- "input": "&rharul",
- "description": "Bad named entity: rharul without a semi-colon",
- "output": [
- [
- "Character",
- "&rharul"
- ]
- ]
- },
- {
- "input": "⥬",
- "description": "Named entity: rharul; with a semi-colon",
- "output": [
- [
- "Character",
- "\u296c"
- ]
- ]
- },
- {
- "input": "&rho",
- "description": "Bad named entity: rho without a semi-colon",
- "output": [
- [
- "Character",
- "&rho"
- ]
- ]
- },
- {
- "input": "ρ",
- "description": "Named entity: rho; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c1"
- ]
- ]
- },
- {
- "input": "&rhov",
- "description": "Bad named entity: rhov without a semi-colon",
- "output": [
- [
- "Character",
- "&rhov"
- ]
- ]
- },
- {
- "input": "ϱ",
- "description": "Named entity: rhov; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f1"
- ]
- ]
- },
- {
- "input": "&rightarrow",
- "description": "Bad named entity: rightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&rightarrow"
- ]
- ]
- },
- {
- "input": "→",
- "description": "Named entity: rightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2192"
- ]
- ]
- },
- {
- "input": "&rightarrowtail",
- "description": "Bad named entity: rightarrowtail without a semi-colon",
- "output": [
- [
- "Character",
- "&rightarrowtail"
- ]
- ]
- },
- {
- "input": "↣",
- "description": "Named entity: rightarrowtail; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a3"
- ]
- ]
- },
- {
- "input": "&rightharpoondown",
- "description": "Bad named entity: rightharpoondown without a semi-colon",
- "output": [
- [
- "Character",
- "&rightharpoondown"
- ]
- ]
- },
- {
- "input": "⇁",
- "description": "Named entity: rightharpoondown; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c1"
- ]
- ]
- },
- {
- "input": "&rightharpoonup",
- "description": "Bad named entity: rightharpoonup without a semi-colon",
- "output": [
- [
- "Character",
- "&rightharpoonup"
- ]
- ]
- },
- {
- "input": "⇀",
- "description": "Named entity: rightharpoonup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c0"
- ]
- ]
- },
- {
- "input": "&rightleftarrows",
- "description": "Bad named entity: rightleftarrows without a semi-colon",
- "output": [
- [
- "Character",
- "&rightleftarrows"
- ]
- ]
- },
- {
- "input": "⇄",
- "description": "Named entity: rightleftarrows; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c4"
- ]
- ]
- },
- {
- "input": "&rightleftharpoons",
- "description": "Bad named entity: rightleftharpoons without a semi-colon",
- "output": [
- [
- "Character",
- "&rightleftharpoons"
- ]
- ]
- },
- {
- "input": "⇌",
- "description": "Named entity: rightleftharpoons; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cc"
- ]
- ]
- },
- {
- "input": "&rightrightarrows",
- "description": "Bad named entity: rightrightarrows without a semi-colon",
- "output": [
- [
- "Character",
- "&rightrightarrows"
- ]
- ]
- },
- {
- "input": "⇉",
- "description": "Named entity: rightrightarrows; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c9"
- ]
- ]
- },
- {
- "input": "&rightsquigarrow",
- "description": "Bad named entity: rightsquigarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&rightsquigarrow"
- ]
- ]
- },
- {
- "input": "↝",
- "description": "Named entity: rightsquigarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219d"
- ]
- ]
- },
- {
- "input": "&rightthreetimes",
- "description": "Bad named entity: rightthreetimes without a semi-colon",
- "output": [
- [
- "Character",
- "&rightthreetimes"
- ]
- ]
- },
- {
- "input": "⋌",
- "description": "Named entity: rightthreetimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22cc"
- ]
- ]
- },
- {
- "input": "&ring",
- "description": "Bad named entity: ring without a semi-colon",
- "output": [
- [
- "Character",
- "&ring"
- ]
- ]
- },
- {
- "input": "˚",
- "description": "Named entity: ring; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02da"
- ]
- ]
- },
- {
- "input": "&risingdotseq",
- "description": "Bad named entity: risingdotseq without a semi-colon",
- "output": [
- [
- "Character",
- "&risingdotseq"
- ]
- ]
- },
- {
- "input": "≓",
- "description": "Named entity: risingdotseq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2253"
- ]
- ]
- },
- {
- "input": "&rlarr",
- "description": "Bad named entity: rlarr without a semi-colon",
- "output": [
- [
- "Character",
- "&rlarr"
- ]
- ]
- },
- {
- "input": "⇄",
- "description": "Named entity: rlarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c4"
- ]
- ]
- },
- {
- "input": "&rlhar",
- "description": "Bad named entity: rlhar without a semi-colon",
- "output": [
- [
- "Character",
- "&rlhar"
- ]
- ]
- },
- {
- "input": "⇌",
- "description": "Named entity: rlhar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21cc"
- ]
- ]
- },
- {
- "input": "&rlm",
- "description": "Bad named entity: rlm without a semi-colon",
- "output": [
- [
- "Character",
- "&rlm"
- ]
- ]
- },
- {
- "input": "",
- "description": "Named entity: rlm; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200f"
- ]
- ]
- },
- {
- "input": "&rmoust",
- "description": "Bad named entity: rmoust without a semi-colon",
- "output": [
- [
- "Character",
- "&rmoust"
- ]
- ]
- },
- {
- "input": "⎱",
- "description": "Named entity: rmoust; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b1"
- ]
- ]
- },
- {
- "input": "&rmoustache",
- "description": "Bad named entity: rmoustache without a semi-colon",
- "output": [
- [
- "Character",
- "&rmoustache"
- ]
- ]
- },
- {
- "input": "⎱",
- "description": "Named entity: rmoustache; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b1"
- ]
- ]
- },
- {
- "input": "&rnmid",
- "description": "Bad named entity: rnmid without a semi-colon",
- "output": [
- [
- "Character",
- "&rnmid"
- ]
- ]
- },
- {
- "input": "⫮",
- "description": "Named entity: rnmid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aee"
- ]
- ]
- },
- {
- "input": "&roang",
- "description": "Bad named entity: roang without a semi-colon",
- "output": [
- [
- "Character",
- "&roang"
- ]
- ]
- },
- {
- "input": "⟭",
- "description": "Named entity: roang; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27ed"
- ]
- ]
- },
- {
- "input": "&roarr",
- "description": "Bad named entity: roarr without a semi-colon",
- "output": [
- [
- "Character",
- "&roarr"
- ]
- ]
- },
- {
- "input": "⇾",
- "description": "Named entity: roarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21fe"
- ]
- ]
- },
- {
- "input": "&robrk",
- "description": "Bad named entity: robrk without a semi-colon",
- "output": [
- [
- "Character",
- "&robrk"
- ]
- ]
- },
- {
- "input": "⟧",
- "description": "Named entity: robrk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27e7"
- ]
- ]
- },
- {
- "input": "&ropar",
- "description": "Bad named entity: ropar without a semi-colon",
- "output": [
- [
- "Character",
- "&ropar"
- ]
- ]
- },
- {
- "input": "⦆",
- "description": "Named entity: ropar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2986"
- ]
- ]
- },
- {
- "input": "&ropf",
- "description": "Bad named entity: ropf without a semi-colon",
- "output": [
- [
- "Character",
- "&ropf"
- ]
- ]
- },
- {
- "input": "𝕣",
- "description": "Named entity: ropf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd63"
- ]
- ]
- },
- {
- "input": "&roplus",
- "description": "Bad named entity: roplus without a semi-colon",
- "output": [
- [
- "Character",
- "&roplus"
- ]
- ]
- },
- {
- "input": "⨮",
- "description": "Named entity: roplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a2e"
- ]
- ]
- },
- {
- "input": "&rotimes",
- "description": "Bad named entity: rotimes without a semi-colon",
- "output": [
- [
- "Character",
- "&rotimes"
- ]
- ]
- },
- {
- "input": "⨵",
- "description": "Named entity: rotimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a35"
- ]
- ]
- },
- {
- "input": "&rpar",
- "description": "Bad named entity: rpar without a semi-colon",
- "output": [
- [
- "Character",
- "&rpar"
- ]
- ]
- },
- {
- "input": ")",
- "description": "Named entity: rpar; with a semi-colon",
- "output": [
- [
- "Character",
- ")"
- ]
- ]
- },
- {
- "input": "&rpargt",
- "description": "Bad named entity: rpargt without a semi-colon",
- "output": [
- [
- "Character",
- "&rpargt"
- ]
- ]
- },
- {
- "input": "⦔",
- "description": "Named entity: rpargt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2994"
- ]
- ]
- },
- {
- "input": "&rppolint",
- "description": "Bad named entity: rppolint without a semi-colon",
- "output": [
- [
- "Character",
- "&rppolint"
- ]
- ]
- },
- {
- "input": "⨒",
- "description": "Named entity: rppolint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a12"
- ]
- ]
- },
- {
- "input": "&rrarr",
- "description": "Bad named entity: rrarr without a semi-colon",
- "output": [
- [
- "Character",
- "&rrarr"
- ]
- ]
- },
- {
- "input": "⇉",
- "description": "Named entity: rrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c9"
- ]
- ]
- },
- {
- "input": "&rsaquo",
- "description": "Bad named entity: rsaquo without a semi-colon",
- "output": [
- [
- "Character",
- "&rsaquo"
- ]
- ]
- },
- {
- "input": "›",
- "description": "Named entity: rsaquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u203a"
- ]
- ]
- },
- {
- "input": "&rscr",
- "description": "Bad named entity: rscr without a semi-colon",
- "output": [
- [
- "Character",
- "&rscr"
- ]
- ]
- },
- {
- "input": "𝓇",
- "description": "Named entity: rscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc7"
- ]
- ]
- },
- {
- "input": "&rsh",
- "description": "Bad named entity: rsh without a semi-colon",
- "output": [
- [
- "Character",
- "&rsh"
- ]
- ]
- },
- {
- "input": "↱",
- "description": "Named entity: rsh; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21b1"
- ]
- ]
- },
- {
- "input": "&rsqb",
- "description": "Bad named entity: rsqb without a semi-colon",
- "output": [
- [
- "Character",
- "&rsqb"
- ]
- ]
- },
- {
- "input": "]",
- "description": "Named entity: rsqb; with a semi-colon",
- "output": [
- [
- "Character",
- "]"
- ]
- ]
- },
- {
- "input": "&rsquo",
- "description": "Bad named entity: rsquo without a semi-colon",
- "output": [
- [
- "Character",
- "&rsquo"
- ]
- ]
- },
- {
- "input": "’",
- "description": "Named entity: rsquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2019"
- ]
- ]
- },
- {
- "input": "&rsquor",
- "description": "Bad named entity: rsquor without a semi-colon",
- "output": [
- [
- "Character",
- "&rsquor"
- ]
- ]
- },
- {
- "input": "’",
- "description": "Named entity: rsquor; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2019"
- ]
- ]
- },
- {
- "input": "&rthree",
- "description": "Bad named entity: rthree without a semi-colon",
- "output": [
- [
- "Character",
- "&rthree"
- ]
- ]
- },
- {
- "input": "⋌",
- "description": "Named entity: rthree; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22cc"
- ]
- ]
- },
- {
- "input": "&rtimes",
- "description": "Bad named entity: rtimes without a semi-colon",
- "output": [
- [
- "Character",
- "&rtimes"
- ]
- ]
- },
- {
- "input": "⋊",
- "description": "Named entity: rtimes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ca"
- ]
- ]
- },
- {
- "input": "&rtri",
- "description": "Bad named entity: rtri without a semi-colon",
- "output": [
- [
- "Character",
- "&rtri"
- ]
- ]
- },
- {
- "input": "▹",
- "description": "Named entity: rtri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b9"
- ]
- ]
- },
- {
- "input": "&rtrie",
- "description": "Bad named entity: rtrie without a semi-colon",
- "output": [
- [
- "Character",
- "&rtrie"
- ]
- ]
- },
- {
- "input": "⊵",
- "description": "Named entity: rtrie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b5"
- ]
- ]
- },
- {
- "input": "&rtrif",
- "description": "Bad named entity: rtrif without a semi-colon",
- "output": [
- [
- "Character",
- "&rtrif"
- ]
- ]
- },
- {
- "input": "▸",
- "description": "Named entity: rtrif; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b8"
- ]
- ]
- },
- {
- "input": "&rtriltri",
- "description": "Bad named entity: rtriltri without a semi-colon",
- "output": [
- [
- "Character",
- "&rtriltri"
- ]
- ]
- },
- {
- "input": "⧎",
- "description": "Named entity: rtriltri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29ce"
- ]
- ]
- },
- {
- "input": "&ruluhar",
- "description": "Bad named entity: ruluhar without a semi-colon",
- "output": [
- [
- "Character",
- "&ruluhar"
- ]
- ]
- },
- {
- "input": "⥨",
- "description": "Named entity: ruluhar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2968"
- ]
- ]
- },
- {
- "input": "&rx",
- "description": "Bad named entity: rx without a semi-colon",
- "output": [
- [
- "Character",
- "&rx"
- ]
- ]
- },
- {
- "input": "℞",
- "description": "Named entity: rx; with a semi-colon",
- "output": [
- [
- "Character",
- "\u211e"
- ]
- ]
- },
- {
- "input": "&sacute",
- "description": "Bad named entity: sacute without a semi-colon",
- "output": [
- [
- "Character",
- "&sacute"
- ]
- ]
- },
- {
- "input": "ś",
- "description": "Named entity: sacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u015b"
- ]
- ]
- },
- {
- "input": "&sbquo",
- "description": "Bad named entity: sbquo without a semi-colon",
- "output": [
- [
- "Character",
- "&sbquo"
- ]
- ]
- },
- {
- "input": "‚",
- "description": "Named entity: sbquo; with a semi-colon",
- "output": [
- [
- "Character",
- "\u201a"
- ]
- ]
- },
- {
- "input": "&sc",
- "description": "Bad named entity: sc without a semi-colon",
- "output": [
- [
- "Character",
- "&sc"
- ]
- ]
- },
- {
- "input": "≻",
- "description": "Named entity: sc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227b"
- ]
- ]
- },
- {
- "input": "&scE",
- "description": "Bad named entity: scE without a semi-colon",
- "output": [
- [
- "Character",
- "&scE"
- ]
- ]
- },
- {
- "input": "⪴",
- "description": "Named entity: scE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab4"
- ]
- ]
- },
- {
- "input": "&scap",
- "description": "Bad named entity: scap without a semi-colon",
- "output": [
- [
- "Character",
- "&scap"
- ]
- ]
- },
- {
- "input": "⪸",
- "description": "Named entity: scap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab8"
- ]
- ]
- },
- {
- "input": "&scaron",
- "description": "Bad named entity: scaron without a semi-colon",
- "output": [
- [
- "Character",
- "&scaron"
- ]
- ]
- },
- {
- "input": "š",
- "description": "Named entity: scaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0161"
- ]
- ]
- },
- {
- "input": "&sccue",
- "description": "Bad named entity: sccue without a semi-colon",
- "output": [
- [
- "Character",
- "&sccue"
- ]
- ]
- },
- {
- "input": "≽",
- "description": "Named entity: sccue; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227d"
- ]
- ]
- },
- {
- "input": "&sce",
- "description": "Bad named entity: sce without a semi-colon",
- "output": [
- [
- "Character",
- "&sce"
- ]
- ]
- },
- {
- "input": "⪰",
- "description": "Named entity: sce; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab0"
- ]
- ]
- },
- {
- "input": "&scedil",
- "description": "Bad named entity: scedil without a semi-colon",
- "output": [
- [
- "Character",
- "&scedil"
- ]
- ]
- },
- {
- "input": "ş",
- "description": "Named entity: scedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u015f"
- ]
- ]
- },
- {
- "input": "&scirc",
- "description": "Bad named entity: scirc without a semi-colon",
- "output": [
- [
- "Character",
- "&scirc"
- ]
- ]
- },
- {
- "input": "ŝ",
- "description": "Named entity: scirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u015d"
- ]
- ]
- },
- {
- "input": "&scnE",
- "description": "Bad named entity: scnE without a semi-colon",
- "output": [
- [
- "Character",
- "&scnE"
- ]
- ]
- },
- {
- "input": "⪶",
- "description": "Named entity: scnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab6"
- ]
- ]
- },
- {
- "input": "&scnap",
- "description": "Bad named entity: scnap without a semi-colon",
- "output": [
- [
- "Character",
- "&scnap"
- ]
- ]
- },
- {
- "input": "⪺",
- "description": "Named entity: scnap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aba"
- ]
- ]
- },
- {
- "input": "&scnsim",
- "description": "Bad named entity: scnsim without a semi-colon",
- "output": [
- [
- "Character",
- "&scnsim"
- ]
- ]
- },
- {
- "input": "⋩",
- "description": "Named entity: scnsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e9"
- ]
- ]
- },
- {
- "input": "&scpolint",
- "description": "Bad named entity: scpolint without a semi-colon",
- "output": [
- [
- "Character",
- "&scpolint"
- ]
- ]
- },
- {
- "input": "⨓",
- "description": "Named entity: scpolint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a13"
- ]
- ]
- },
- {
- "input": "&scsim",
- "description": "Bad named entity: scsim without a semi-colon",
- "output": [
- [
- "Character",
- "&scsim"
- ]
- ]
- },
- {
- "input": "≿",
- "description": "Named entity: scsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227f"
- ]
- ]
- },
- {
- "input": "&scy",
- "description": "Bad named entity: scy without a semi-colon",
- "output": [
- [
- "Character",
- "&scy"
- ]
- ]
- },
- {
- "input": "с",
- "description": "Named entity: scy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0441"
- ]
- ]
- },
- {
- "input": "&sdot",
- "description": "Bad named entity: sdot without a semi-colon",
- "output": [
- [
- "Character",
- "&sdot"
- ]
- ]
- },
- {
- "input": "⋅",
- "description": "Named entity: sdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c5"
- ]
- ]
- },
- {
- "input": "&sdotb",
- "description": "Bad named entity: sdotb without a semi-colon",
- "output": [
- [
- "Character",
- "&sdotb"
- ]
- ]
- },
- {
- "input": "⊡",
- "description": "Named entity: sdotb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a1"
- ]
- ]
- },
- {
- "input": "&sdote",
- "description": "Bad named entity: sdote without a semi-colon",
- "output": [
- [
- "Character",
- "&sdote"
- ]
- ]
- },
- {
- "input": "⩦",
- "description": "Named entity: sdote; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a66"
- ]
- ]
- },
- {
- "input": "&seArr",
- "description": "Bad named entity: seArr without a semi-colon",
- "output": [
- [
- "Character",
- "&seArr"
- ]
- ]
- },
- {
- "input": "⇘",
- "description": "Named entity: seArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d8"
- ]
- ]
- },
- {
- "input": "&searhk",
- "description": "Bad named entity: searhk without a semi-colon",
- "output": [
- [
- "Character",
- "&searhk"
- ]
- ]
- },
- {
- "input": "⤥",
- "description": "Named entity: searhk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2925"
- ]
- ]
- },
- {
- "input": "&searr",
- "description": "Bad named entity: searr without a semi-colon",
- "output": [
- [
- "Character",
- "&searr"
- ]
- ]
- },
- {
- "input": "↘",
- "description": "Named entity: searr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2198"
- ]
- ]
- },
- {
- "input": "&searrow",
- "description": "Bad named entity: searrow without a semi-colon",
- "output": [
- [
- "Character",
- "&searrow"
- ]
- ]
- },
- {
- "input": "↘",
- "description": "Named entity: searrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2198"
- ]
- ]
- },
- {
- "input": "§",
- "description": "Named entity: sect without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a7"
- ]
- ]
- },
- {
- "input": "§",
- "description": "Named entity: sect; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a7"
- ]
- ]
- },
- {
- "input": "&semi",
- "description": "Bad named entity: semi without a semi-colon",
- "output": [
- [
- "Character",
- "&semi"
- ]
- ]
- },
- {
- "input": ";",
- "description": "Named entity: semi; with a semi-colon",
- "output": [
- [
- "Character",
- ";"
- ]
- ]
- },
- {
- "input": "&seswar",
- "description": "Bad named entity: seswar without a semi-colon",
- "output": [
- [
- "Character",
- "&seswar"
- ]
- ]
- },
- {
- "input": "⤩",
- "description": "Named entity: seswar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2929"
- ]
- ]
- },
- {
- "input": "&setminus",
- "description": "Bad named entity: setminus without a semi-colon",
- "output": [
- [
- "Character",
- "&setminus"
- ]
- ]
- },
- {
- "input": "∖",
- "description": "Named entity: setminus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2216"
- ]
- ]
- },
- {
- "input": "&setmn",
- "description": "Bad named entity: setmn without a semi-colon",
- "output": [
- [
- "Character",
- "&setmn"
- ]
- ]
- },
- {
- "input": "∖",
- "description": "Named entity: setmn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2216"
- ]
- ]
- },
- {
- "input": "&sext",
- "description": "Bad named entity: sext without a semi-colon",
- "output": [
- [
- "Character",
- "&sext"
- ]
- ]
- },
- {
- "input": "✶",
- "description": "Named entity: sext; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2736"
- ]
- ]
- },
- {
- "input": "&sfr",
- "description": "Bad named entity: sfr without a semi-colon",
- "output": [
- [
- "Character",
- "&sfr"
- ]
- ]
- },
- {
- "input": "𝔰",
- "description": "Named entity: sfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd30"
- ]
- ]
- },
- {
- "input": "&sfrown",
- "description": "Bad named entity: sfrown without a semi-colon",
- "output": [
- [
- "Character",
- "&sfrown"
- ]
- ]
- },
- {
- "input": "⌢",
- "description": "Named entity: sfrown; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2322"
- ]
- ]
- },
- {
- "input": "&sharp",
- "description": "Bad named entity: sharp without a semi-colon",
- "output": [
- [
- "Character",
- "&sharp"
- ]
- ]
- },
- {
- "input": "♯",
- "description": "Named entity: sharp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u266f"
- ]
- ]
- },
- {
- "input": "&shchcy",
- "description": "Bad named entity: shchcy without a semi-colon",
- "output": [
- [
- "Character",
- "&shchcy"
- ]
- ]
- },
- {
- "input": "щ",
- "description": "Named entity: shchcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0449"
- ]
- ]
- },
- {
- "input": "&shcy",
- "description": "Bad named entity: shcy without a semi-colon",
- "output": [
- [
- "Character",
- "&shcy"
- ]
- ]
- },
- {
- "input": "ш",
- "description": "Named entity: shcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0448"
- ]
- ]
- },
- {
- "input": "&shortmid",
- "description": "Bad named entity: shortmid without a semi-colon",
- "output": [
- [
- "Character",
- "&shortmid"
- ]
- ]
- },
- {
- "input": "∣",
- "description": "Named entity: shortmid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2223"
- ]
- ]
- },
- {
- "input": "&shortparallel",
- "description": "Bad named entity: shortparallel without a semi-colon",
- "output": [
- [
- "Character",
- "&shortparallel"
- ]
- ]
- },
- {
- "input": "∥",
- "description": "Named entity: shortparallel; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2225"
- ]
- ]
- },
- {
- "input": "­",
- "description": "Named entity: shy without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ad"
- ]
- ]
- },
- {
- "input": "",
- "description": "Named entity: shy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ad"
- ]
- ]
- },
- {
- "input": "&sigma",
- "description": "Bad named entity: sigma without a semi-colon",
- "output": [
- [
- "Character",
- "&sigma"
- ]
- ]
- },
- {
- "input": "σ",
- "description": "Named entity: sigma; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c3"
- ]
- ]
- },
- {
- "input": "&sigmaf",
- "description": "Bad named entity: sigmaf without a semi-colon",
- "output": [
- [
- "Character",
- "&sigmaf"
- ]
- ]
- },
- {
- "input": "ς",
- "description": "Named entity: sigmaf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c2"
- ]
- ]
- },
- {
- "input": "&sigmav",
- "description": "Bad named entity: sigmav without a semi-colon",
- "output": [
- [
- "Character",
- "&sigmav"
- ]
- ]
- },
- {
- "input": "ς",
- "description": "Named entity: sigmav; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c2"
- ]
- ]
- },
- {
- "input": "&sim",
- "description": "Bad named entity: sim without a semi-colon",
- "output": [
- [
- "Character",
- "&sim"
- ]
- ]
- },
- {
- "input": "∼",
- "description": "Named entity: sim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223c"
- ]
- ]
- },
- {
- "input": "&simdot",
- "description": "Bad named entity: simdot without a semi-colon",
- "output": [
- [
- "Character",
- "&simdot"
- ]
- ]
- },
- {
- "input": "⩪",
- "description": "Named entity: simdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a6a"
- ]
- ]
- },
- {
- "input": "&sime",
- "description": "Bad named entity: sime without a semi-colon",
- "output": [
- [
- "Character",
- "&sime"
- ]
- ]
- },
- {
- "input": "≃",
- "description": "Named entity: sime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2243"
- ]
- ]
- },
- {
- "input": "&simeq",
- "description": "Bad named entity: simeq without a semi-colon",
- "output": [
- [
- "Character",
- "&simeq"
- ]
- ]
- },
- {
- "input": "≃",
- "description": "Named entity: simeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2243"
- ]
- ]
- },
- {
- "input": "&simg",
- "description": "Bad named entity: simg without a semi-colon",
- "output": [
- [
- "Character",
- "&simg"
- ]
- ]
- },
- {
- "input": "⪞",
- "description": "Named entity: simg; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a9e"
- ]
- ]
- },
- {
- "input": "&simgE",
- "description": "Bad named entity: simgE without a semi-colon",
- "output": [
- [
- "Character",
- "&simgE"
- ]
- ]
- },
- {
- "input": "⪠",
- "description": "Named entity: simgE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aa0"
- ]
- ]
- },
- {
- "input": "&siml",
- "description": "Bad named entity: siml without a semi-colon",
- "output": [
- [
- "Character",
- "&siml"
- ]
- ]
- },
- {
- "input": "⪝",
- "description": "Named entity: siml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a9d"
- ]
- ]
- },
- {
- "input": "&simlE",
- "description": "Bad named entity: simlE without a semi-colon",
- "output": [
- [
- "Character",
- "&simlE"
- ]
- ]
- },
- {
- "input": "⪟",
- "description": "Named entity: simlE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a9f"
- ]
- ]
- },
- {
- "input": "&simne",
- "description": "Bad named entity: simne without a semi-colon",
- "output": [
- [
- "Character",
- "&simne"
- ]
- ]
- },
- {
- "input": "≆",
- "description": "Named entity: simne; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2246"
- ]
- ]
- },
- {
- "input": "&simplus",
- "description": "Bad named entity: simplus without a semi-colon",
- "output": [
- [
- "Character",
- "&simplus"
- ]
- ]
- },
- {
- "input": "⨤",
- "description": "Named entity: simplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a24"
- ]
- ]
- },
- {
- "input": "&simrarr",
- "description": "Bad named entity: simrarr without a semi-colon",
- "output": [
- [
- "Character",
- "&simrarr"
- ]
- ]
- },
- {
- "input": "⥲",
- "description": "Named entity: simrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2972"
- ]
- ]
- },
- {
- "input": "&slarr",
- "description": "Bad named entity: slarr without a semi-colon",
- "output": [
- [
- "Character",
- "&slarr"
- ]
- ]
- },
- {
- "input": "←",
- "description": "Named entity: slarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2190"
- ]
- ]
- },
- {
- "input": "&smallsetminus",
- "description": "Bad named entity: smallsetminus without a semi-colon",
- "output": [
- [
- "Character",
- "&smallsetminus"
- ]
- ]
- },
- {
- "input": "∖",
- "description": "Named entity: smallsetminus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2216"
- ]
- ]
- },
- {
- "input": "&smashp",
- "description": "Bad named entity: smashp without a semi-colon",
- "output": [
- [
- "Character",
- "&smashp"
- ]
- ]
- },
- {
- "input": "⨳",
- "description": "Named entity: smashp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a33"
- ]
- ]
- },
- {
- "input": "&smeparsl",
- "description": "Bad named entity: smeparsl without a semi-colon",
- "output": [
- [
- "Character",
- "&smeparsl"
- ]
- ]
- },
- {
- "input": "⧤",
- "description": "Named entity: smeparsl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29e4"
- ]
- ]
- },
- {
- "input": "&smid",
- "description": "Bad named entity: smid without a semi-colon",
- "output": [
- [
- "Character",
- "&smid"
- ]
- ]
- },
- {
- "input": "∣",
- "description": "Named entity: smid; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2223"
- ]
- ]
- },
- {
- "input": "&smile",
- "description": "Bad named entity: smile without a semi-colon",
- "output": [
- [
- "Character",
- "&smile"
- ]
- ]
- },
- {
- "input": "⌣",
- "description": "Named entity: smile; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2323"
- ]
- ]
- },
- {
- "input": "&smt",
- "description": "Bad named entity: smt without a semi-colon",
- "output": [
- [
- "Character",
- "&smt"
- ]
- ]
- },
- {
- "input": "⪪",
- "description": "Named entity: smt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aaa"
- ]
- ]
- },
- {
- "input": "&smte",
- "description": "Bad named entity: smte without a semi-colon",
- "output": [
- [
- "Character",
- "&smte"
- ]
- ]
- },
- {
- "input": "⪬",
- "description": "Named entity: smte; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aac"
- ]
- ]
- },
- {
- "input": "&smtes",
- "description": "Bad named entity: smtes without a semi-colon",
- "output": [
- [
- "Character",
- "&smtes"
- ]
- ]
- },
- {
- "input": "⪬︀",
- "description": "Named entity: smtes; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aac\ufe00"
- ]
- ]
- },
- {
- "input": "&softcy",
- "description": "Bad named entity: softcy without a semi-colon",
- "output": [
- [
- "Character",
- "&softcy"
- ]
- ]
- },
- {
- "input": "ь",
- "description": "Named entity: softcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u044c"
- ]
- ]
- },
- {
- "input": "&sol",
- "description": "Bad named entity: sol without a semi-colon",
- "output": [
- [
- "Character",
- "&sol"
- ]
- ]
- },
- {
- "input": "/",
- "description": "Named entity: sol; with a semi-colon",
- "output": [
- [
- "Character",
- "/"
- ]
- ]
- },
- {
- "input": "&solb",
- "description": "Bad named entity: solb without a semi-colon",
- "output": [
- [
- "Character",
- "&solb"
- ]
- ]
- },
- {
- "input": "⧄",
- "description": "Named entity: solb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29c4"
- ]
- ]
- },
- {
- "input": "&solbar",
- "description": "Bad named entity: solbar without a semi-colon",
- "output": [
- [
- "Character",
- "&solbar"
- ]
- ]
- },
- {
- "input": "⌿",
- "description": "Named entity: solbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u233f"
- ]
- ]
- },
- {
- "input": "&sopf",
- "description": "Bad named entity: sopf without a semi-colon",
- "output": [
- [
- "Character",
- "&sopf"
- ]
- ]
- },
- {
- "input": "𝕤",
- "description": "Named entity: sopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd64"
- ]
- ]
- },
- {
- "input": "&spades",
- "description": "Bad named entity: spades without a semi-colon",
- "output": [
- [
- "Character",
- "&spades"
- ]
- ]
- },
- {
- "input": "♠",
- "description": "Named entity: spades; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2660"
- ]
- ]
- },
- {
- "input": "&spadesuit",
- "description": "Bad named entity: spadesuit without a semi-colon",
- "output": [
- [
- "Character",
- "&spadesuit"
- ]
- ]
- },
- {
- "input": "♠",
- "description": "Named entity: spadesuit; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2660"
- ]
- ]
- },
- {
- "input": "&spar",
- "description": "Bad named entity: spar without a semi-colon",
- "output": [
- [
- "Character",
- "&spar"
- ]
- ]
- },
- {
- "input": "∥",
- "description": "Named entity: spar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2225"
- ]
- ]
- },
- {
- "input": "&sqcap",
- "description": "Bad named entity: sqcap without a semi-colon",
- "output": [
- [
- "Character",
- "&sqcap"
- ]
- ]
- },
- {
- "input": "⊓",
- "description": "Named entity: sqcap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2293"
- ]
- ]
- },
- {
- "input": "&sqcaps",
- "description": "Bad named entity: sqcaps without a semi-colon",
- "output": [
- [
- "Character",
- "&sqcaps"
- ]
- ]
- },
- {
- "input": "⊓︀",
- "description": "Named entity: sqcaps; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2293\ufe00"
- ]
- ]
- },
- {
- "input": "&sqcup",
- "description": "Bad named entity: sqcup without a semi-colon",
- "output": [
- [
- "Character",
- "&sqcup"
- ]
- ]
- },
- {
- "input": "⊔",
- "description": "Named entity: sqcup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2294"
- ]
- ]
- },
- {
- "input": "&sqcups",
- "description": "Bad named entity: sqcups without a semi-colon",
- "output": [
- [
- "Character",
- "&sqcups"
- ]
- ]
- },
- {
- "input": "⊔︀",
- "description": "Named entity: sqcups; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2294\ufe00"
- ]
- ]
- },
- {
- "input": "&sqsub",
- "description": "Bad named entity: sqsub without a semi-colon",
- "output": [
- [
- "Character",
- "&sqsub"
- ]
- ]
- },
- {
- "input": "⊏",
- "description": "Named entity: sqsub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228f"
- ]
- ]
- },
- {
- "input": "&sqsube",
- "description": "Bad named entity: sqsube without a semi-colon",
- "output": [
- [
- "Character",
- "&sqsube"
- ]
- ]
- },
- {
- "input": "⊑",
- "description": "Named entity: sqsube; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2291"
- ]
- ]
- },
- {
- "input": "&sqsubset",
- "description": "Bad named entity: sqsubset without a semi-colon",
- "output": [
- [
- "Character",
- "&sqsubset"
- ]
- ]
- },
- {
- "input": "⊏",
- "description": "Named entity: sqsubset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228f"
- ]
- ]
- },
- {
- "input": "&sqsubseteq",
- "description": "Bad named entity: sqsubseteq without a semi-colon",
- "output": [
- [
- "Character",
- "&sqsubseteq"
- ]
- ]
- },
- {
- "input": "⊑",
- "description": "Named entity: sqsubseteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2291"
- ]
- ]
- },
- {
- "input": "&sqsup",
- "description": "Bad named entity: sqsup without a semi-colon",
- "output": [
- [
- "Character",
- "&sqsup"
- ]
- ]
- },
- {
- "input": "⊐",
- "description": "Named entity: sqsup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2290"
- ]
- ]
- },
- {
- "input": "&sqsupe",
- "description": "Bad named entity: sqsupe without a semi-colon",
- "output": [
- [
- "Character",
- "&sqsupe"
- ]
- ]
- },
- {
- "input": "⊒",
- "description": "Named entity: sqsupe; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2292"
- ]
- ]
- },
- {
- "input": "&sqsupset",
- "description": "Bad named entity: sqsupset without a semi-colon",
- "output": [
- [
- "Character",
- "&sqsupset"
- ]
- ]
- },
- {
- "input": "⊐",
- "description": "Named entity: sqsupset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2290"
- ]
- ]
- },
- {
- "input": "&sqsupseteq",
- "description": "Bad named entity: sqsupseteq without a semi-colon",
- "output": [
- [
- "Character",
- "&sqsupseteq"
- ]
- ]
- },
- {
- "input": "⊒",
- "description": "Named entity: sqsupseteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2292"
- ]
- ]
- },
- {
- "input": "&squ",
- "description": "Bad named entity: squ without a semi-colon",
- "output": [
- [
- "Character",
- "&squ"
- ]
- ]
- },
- {
- "input": "□",
- "description": "Named entity: squ; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25a1"
- ]
- ]
- },
- {
- "input": "&square",
- "description": "Bad named entity: square without a semi-colon",
- "output": [
- [
- "Character",
- "&square"
- ]
- ]
- },
- {
- "input": "□",
- "description": "Named entity: square; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25a1"
- ]
- ]
- },
- {
- "input": "&squarf",
- "description": "Bad named entity: squarf without a semi-colon",
- "output": [
- [
- "Character",
- "&squarf"
- ]
- ]
- },
- {
- "input": "▪",
- "description": "Named entity: squarf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25aa"
- ]
- ]
- },
- {
- "input": "&squf",
- "description": "Bad named entity: squf without a semi-colon",
- "output": [
- [
- "Character",
- "&squf"
- ]
- ]
- },
- {
- "input": "▪",
- "description": "Named entity: squf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25aa"
- ]
- ]
- },
- {
- "input": "&srarr",
- "description": "Bad named entity: srarr without a semi-colon",
- "output": [
- [
- "Character",
- "&srarr"
- ]
- ]
- },
- {
- "input": "→",
- "description": "Named entity: srarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2192"
- ]
- ]
- },
- {
- "input": "&sscr",
- "description": "Bad named entity: sscr without a semi-colon",
- "output": [
- [
- "Character",
- "&sscr"
- ]
- ]
- },
- {
- "input": "𝓈",
- "description": "Named entity: sscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc8"
- ]
- ]
- },
- {
- "input": "&ssetmn",
- "description": "Bad named entity: ssetmn without a semi-colon",
- "output": [
- [
- "Character",
- "&ssetmn"
- ]
- ]
- },
- {
- "input": "∖",
- "description": "Named entity: ssetmn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2216"
- ]
- ]
- },
- {
- "input": "&ssmile",
- "description": "Bad named entity: ssmile without a semi-colon",
- "output": [
- [
- "Character",
- "&ssmile"
- ]
- ]
- },
- {
- "input": "⌣",
- "description": "Named entity: ssmile; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2323"
- ]
- ]
- },
- {
- "input": "&sstarf",
- "description": "Bad named entity: sstarf without a semi-colon",
- "output": [
- [
- "Character",
- "&sstarf"
- ]
- ]
- },
- {
- "input": "⋆",
- "description": "Named entity: sstarf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c6"
- ]
- ]
- },
- {
- "input": "&star",
- "description": "Bad named entity: star without a semi-colon",
- "output": [
- [
- "Character",
- "&star"
- ]
- ]
- },
- {
- "input": "☆",
- "description": "Named entity: star; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2606"
- ]
- ]
- },
- {
- "input": "&starf",
- "description": "Bad named entity: starf without a semi-colon",
- "output": [
- [
- "Character",
- "&starf"
- ]
- ]
- },
- {
- "input": "★",
- "description": "Named entity: starf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2605"
- ]
- ]
- },
- {
- "input": "&straightepsilon",
- "description": "Bad named entity: straightepsilon without a semi-colon",
- "output": [
- [
- "Character",
- "&straightepsilon"
- ]
- ]
- },
- {
- "input": "ϵ",
- "description": "Named entity: straightepsilon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f5"
- ]
- ]
- },
- {
- "input": "&straightphi",
- "description": "Bad named entity: straightphi without a semi-colon",
- "output": [
- [
- "Character",
- "&straightphi"
- ]
- ]
- },
- {
- "input": "ϕ",
- "description": "Named entity: straightphi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d5"
- ]
- ]
- },
- {
- "input": "&strns",
- "description": "Bad named entity: strns without a semi-colon",
- "output": [
- [
- "Character",
- "&strns"
- ]
- ]
- },
- {
- "input": "¯",
- "description": "Named entity: strns; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00af"
- ]
- ]
- },
- {
- "input": "&sub",
- "description": "Bad named entity: sub without a semi-colon",
- "output": [
- [
- "Character",
- "&sub"
- ]
- ]
- },
- {
- "input": "⊂",
- "description": "Named entity: sub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2282"
- ]
- ]
- },
- {
- "input": "&subE",
- "description": "Bad named entity: subE without a semi-colon",
- "output": [
- [
- "Character",
- "&subE"
- ]
- ]
- },
- {
- "input": "⫅",
- "description": "Named entity: subE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac5"
- ]
- ]
- },
- {
- "input": "&subdot",
- "description": "Bad named entity: subdot without a semi-colon",
- "output": [
- [
- "Character",
- "&subdot"
- ]
- ]
- },
- {
- "input": "⪽",
- "description": "Named entity: subdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2abd"
- ]
- ]
- },
- {
- "input": "&sube",
- "description": "Bad named entity: sube without a semi-colon",
- "output": [
- [
- "Character",
- "&sube"
- ]
- ]
- },
- {
- "input": "⊆",
- "description": "Named entity: sube; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2286"
- ]
- ]
- },
- {
- "input": "&subedot",
- "description": "Bad named entity: subedot without a semi-colon",
- "output": [
- [
- "Character",
- "&subedot"
- ]
- ]
- },
- {
- "input": "⫃",
- "description": "Named entity: subedot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac3"
- ]
- ]
- },
- {
- "input": "&submult",
- "description": "Bad named entity: submult without a semi-colon",
- "output": [
- [
- "Character",
- "&submult"
- ]
- ]
- },
- {
- "input": "⫁",
- "description": "Named entity: submult; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac1"
- ]
- ]
- },
- {
- "input": "&subnE",
- "description": "Bad named entity: subnE without a semi-colon",
- "output": [
- [
- "Character",
- "&subnE"
- ]
- ]
- },
- {
- "input": "⫋",
- "description": "Named entity: subnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acb"
- ]
- ]
- },
- {
- "input": "&subne",
- "description": "Bad named entity: subne without a semi-colon",
- "output": [
- [
- "Character",
- "&subne"
- ]
- ]
- },
- {
- "input": "⊊",
- "description": "Named entity: subne; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228a"
- ]
- ]
- },
- {
- "input": "&subplus",
- "description": "Bad named entity: subplus without a semi-colon",
- "output": [
- [
- "Character",
- "&subplus"
- ]
- ]
- },
- {
- "input": "⪿",
- "description": "Named entity: subplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2abf"
- ]
- ]
- },
- {
- "input": "&subrarr",
- "description": "Bad named entity: subrarr without a semi-colon",
- "output": [
- [
- "Character",
- "&subrarr"
- ]
- ]
- },
- {
- "input": "⥹",
- "description": "Named entity: subrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2979"
- ]
- ]
- },
- {
- "input": "&subset",
- "description": "Bad named entity: subset without a semi-colon",
- "output": [
- [
- "Character",
- "&subset"
- ]
- ]
- },
- {
- "input": "⊂",
- "description": "Named entity: subset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2282"
- ]
- ]
- },
- {
- "input": "&subseteq",
- "description": "Bad named entity: subseteq without a semi-colon",
- "output": [
- [
- "Character",
- "&subseteq"
- ]
- ]
- },
- {
- "input": "⊆",
- "description": "Named entity: subseteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2286"
- ]
- ]
- },
- {
- "input": "&subseteqq",
- "description": "Bad named entity: subseteqq without a semi-colon",
- "output": [
- [
- "Character",
- "&subseteqq"
- ]
- ]
- },
- {
- "input": "⫅",
- "description": "Named entity: subseteqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac5"
- ]
- ]
- },
- {
- "input": "&subsetneq",
- "description": "Bad named entity: subsetneq without a semi-colon",
- "output": [
- [
- "Character",
- "&subsetneq"
- ]
- ]
- },
- {
- "input": "⊊",
- "description": "Named entity: subsetneq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228a"
- ]
- ]
- },
- {
- "input": "&subsetneqq",
- "description": "Bad named entity: subsetneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&subsetneqq"
- ]
- ]
- },
- {
- "input": "⫋",
- "description": "Named entity: subsetneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acb"
- ]
- ]
- },
- {
- "input": "&subsim",
- "description": "Bad named entity: subsim without a semi-colon",
- "output": [
- [
- "Character",
- "&subsim"
- ]
- ]
- },
- {
- "input": "⫇",
- "description": "Named entity: subsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac7"
- ]
- ]
- },
- {
- "input": "&subsub",
- "description": "Bad named entity: subsub without a semi-colon",
- "output": [
- [
- "Character",
- "&subsub"
- ]
- ]
- },
- {
- "input": "⫕",
- "description": "Named entity: subsub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad5"
- ]
- ]
- },
- {
- "input": "&subsup",
- "description": "Bad named entity: subsup without a semi-colon",
- "output": [
- [
- "Character",
- "&subsup"
- ]
- ]
- },
- {
- "input": "⫓",
- "description": "Named entity: subsup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad3"
- ]
- ]
- },
- {
- "input": "&succ",
- "description": "Bad named entity: succ without a semi-colon",
- "output": [
- [
- "Character",
- "&succ"
- ]
- ]
- },
- {
- "input": "≻",
- "description": "Named entity: succ; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227b"
- ]
- ]
- },
- {
- "input": "&succapprox",
- "description": "Bad named entity: succapprox without a semi-colon",
- "output": [
- [
- "Character",
- "&succapprox"
- ]
- ]
- },
- {
- "input": "⪸",
- "description": "Named entity: succapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab8"
- ]
- ]
- },
- {
- "input": "&succcurlyeq",
- "description": "Bad named entity: succcurlyeq without a semi-colon",
- "output": [
- [
- "Character",
- "&succcurlyeq"
- ]
- ]
- },
- {
- "input": "≽",
- "description": "Named entity: succcurlyeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227d"
- ]
- ]
- },
- {
- "input": "&succeq",
- "description": "Bad named entity: succeq without a semi-colon",
- "output": [
- [
- "Character",
- "&succeq"
- ]
- ]
- },
- {
- "input": "⪰",
- "description": "Named entity: succeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab0"
- ]
- ]
- },
- {
- "input": "&succnapprox",
- "description": "Bad named entity: succnapprox without a semi-colon",
- "output": [
- [
- "Character",
- "&succnapprox"
- ]
- ]
- },
- {
- "input": "⪺",
- "description": "Named entity: succnapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2aba"
- ]
- ]
- },
- {
- "input": "&succneqq",
- "description": "Bad named entity: succneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&succneqq"
- ]
- ]
- },
- {
- "input": "⪶",
- "description": "Named entity: succneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ab6"
- ]
- ]
- },
- {
- "input": "&succnsim",
- "description": "Bad named entity: succnsim without a semi-colon",
- "output": [
- [
- "Character",
- "&succnsim"
- ]
- ]
- },
- {
- "input": "⋩",
- "description": "Named entity: succnsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22e9"
- ]
- ]
- },
- {
- "input": "&succsim",
- "description": "Bad named entity: succsim without a semi-colon",
- "output": [
- [
- "Character",
- "&succsim"
- ]
- ]
- },
- {
- "input": "≿",
- "description": "Named entity: succsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u227f"
- ]
- ]
- },
- {
- "input": "&sum",
- "description": "Bad named entity: sum without a semi-colon",
- "output": [
- [
- "Character",
- "&sum"
- ]
- ]
- },
- {
- "input": "∑",
- "description": "Named entity: sum; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2211"
- ]
- ]
- },
- {
- "input": "&sung",
- "description": "Bad named entity: sung without a semi-colon",
- "output": [
- [
- "Character",
- "&sung"
- ]
- ]
- },
- {
- "input": "♪",
- "description": "Named entity: sung; with a semi-colon",
- "output": [
- [
- "Character",
- "\u266a"
- ]
- ]
- },
- {
- "input": "&sup",
- "description": "Bad named entity: sup without a semi-colon",
- "output": [
- [
- "Character",
- "&sup"
- ]
- ]
- },
- {
- "input": "¹",
- "description": "Named entity: sup1 without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b9"
- ]
- ]
- },
- {
- "input": "¹",
- "description": "Named entity: sup1; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b9"
- ]
- ]
- },
- {
- "input": "²",
- "description": "Named entity: sup2 without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b2"
- ]
- ]
- },
- {
- "input": "²",
- "description": "Named entity: sup2; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b2"
- ]
- ]
- },
- {
- "input": "³",
- "description": "Named entity: sup3 without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00b3"
- ]
- ]
- },
- {
- "input": "³",
- "description": "Named entity: sup3; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00b3"
- ]
- ]
- },
- {
- "input": "⊃",
- "description": "Named entity: sup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2283"
- ]
- ]
- },
- {
- "input": "&supE",
- "description": "Bad named entity: supE without a semi-colon",
- "output": [
- [
- "Character",
- "&supE"
- ]
- ]
- },
- {
- "input": "⫆",
- "description": "Named entity: supE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac6"
- ]
- ]
- },
- {
- "input": "&supdot",
- "description": "Bad named entity: supdot without a semi-colon",
- "output": [
- [
- "Character",
- "&supdot"
- ]
- ]
- },
- {
- "input": "⪾",
- "description": "Named entity: supdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2abe"
- ]
- ]
- },
- {
- "input": "&supdsub",
- "description": "Bad named entity: supdsub without a semi-colon",
- "output": [
- [
- "Character",
- "&supdsub"
- ]
- ]
- },
- {
- "input": "⫘",
- "description": "Named entity: supdsub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad8"
- ]
- ]
- },
- {
- "input": "&supe",
- "description": "Bad named entity: supe without a semi-colon",
- "output": [
- [
- "Character",
- "&supe"
- ]
- ]
- },
- {
- "input": "⊇",
- "description": "Named entity: supe; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2287"
- ]
- ]
- },
- {
- "input": "&supedot",
- "description": "Bad named entity: supedot without a semi-colon",
- "output": [
- [
- "Character",
- "&supedot"
- ]
- ]
- },
- {
- "input": "⫄",
- "description": "Named entity: supedot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac4"
- ]
- ]
- },
- {
- "input": "&suphsol",
- "description": "Bad named entity: suphsol without a semi-colon",
- "output": [
- [
- "Character",
- "&suphsol"
- ]
- ]
- },
- {
- "input": "⟉",
- "description": "Named entity: suphsol; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27c9"
- ]
- ]
- },
- {
- "input": "&suphsub",
- "description": "Bad named entity: suphsub without a semi-colon",
- "output": [
- [
- "Character",
- "&suphsub"
- ]
- ]
- },
- {
- "input": "⫗",
- "description": "Named entity: suphsub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad7"
- ]
- ]
- },
- {
- "input": "&suplarr",
- "description": "Bad named entity: suplarr without a semi-colon",
- "output": [
- [
- "Character",
- "&suplarr"
- ]
- ]
- },
- {
- "input": "⥻",
- "description": "Named entity: suplarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u297b"
- ]
- ]
- },
- {
- "input": "&supmult",
- "description": "Bad named entity: supmult without a semi-colon",
- "output": [
- [
- "Character",
- "&supmult"
- ]
- ]
- },
- {
- "input": "⫂",
- "description": "Named entity: supmult; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac2"
- ]
- ]
- },
- {
- "input": "&supnE",
- "description": "Bad named entity: supnE without a semi-colon",
- "output": [
- [
- "Character",
- "&supnE"
- ]
- ]
- },
- {
- "input": "⫌",
- "description": "Named entity: supnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acc"
- ]
- ]
- },
- {
- "input": "&supne",
- "description": "Bad named entity: supne without a semi-colon",
- "output": [
- [
- "Character",
- "&supne"
- ]
- ]
- },
- {
- "input": "⊋",
- "description": "Named entity: supne; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228b"
- ]
- ]
- },
- {
- "input": "&supplus",
- "description": "Bad named entity: supplus without a semi-colon",
- "output": [
- [
- "Character",
- "&supplus"
- ]
- ]
- },
- {
- "input": "⫀",
- "description": "Named entity: supplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac0"
- ]
- ]
- },
- {
- "input": "&supset",
- "description": "Bad named entity: supset without a semi-colon",
- "output": [
- [
- "Character",
- "&supset"
- ]
- ]
- },
- {
- "input": "⊃",
- "description": "Named entity: supset; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2283"
- ]
- ]
- },
- {
- "input": "&supseteq",
- "description": "Bad named entity: supseteq without a semi-colon",
- "output": [
- [
- "Character",
- "&supseteq"
- ]
- ]
- },
- {
- "input": "⊇",
- "description": "Named entity: supseteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2287"
- ]
- ]
- },
- {
- "input": "&supseteqq",
- "description": "Bad named entity: supseteqq without a semi-colon",
- "output": [
- [
- "Character",
- "&supseteqq"
- ]
- ]
- },
- {
- "input": "⫆",
- "description": "Named entity: supseteqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac6"
- ]
- ]
- },
- {
- "input": "&supsetneq",
- "description": "Bad named entity: supsetneq without a semi-colon",
- "output": [
- [
- "Character",
- "&supsetneq"
- ]
- ]
- },
- {
- "input": "⊋",
- "description": "Named entity: supsetneq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228b"
- ]
- ]
- },
- {
- "input": "&supsetneqq",
- "description": "Bad named entity: supsetneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&supsetneqq"
- ]
- ]
- },
- {
- "input": "⫌",
- "description": "Named entity: supsetneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acc"
- ]
- ]
- },
- {
- "input": "&supsim",
- "description": "Bad named entity: supsim without a semi-colon",
- "output": [
- [
- "Character",
- "&supsim"
- ]
- ]
- },
- {
- "input": "⫈",
- "description": "Named entity: supsim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ac8"
- ]
- ]
- },
- {
- "input": "&supsub",
- "description": "Bad named entity: supsub without a semi-colon",
- "output": [
- [
- "Character",
- "&supsub"
- ]
- ]
- },
- {
- "input": "⫔",
- "description": "Named entity: supsub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad4"
- ]
- ]
- },
- {
- "input": "&supsup",
- "description": "Bad named entity: supsup without a semi-colon",
- "output": [
- [
- "Character",
- "&supsup"
- ]
- ]
- },
- {
- "input": "⫖",
- "description": "Named entity: supsup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ad6"
- ]
- ]
- },
- {
- "input": "&swArr",
- "description": "Bad named entity: swArr without a semi-colon",
- "output": [
- [
- "Character",
- "&swArr"
- ]
- ]
- },
- {
- "input": "⇙",
- "description": "Named entity: swArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d9"
- ]
- ]
- },
- {
- "input": "&swarhk",
- "description": "Bad named entity: swarhk without a semi-colon",
- "output": [
- [
- "Character",
- "&swarhk"
- ]
- ]
- },
- {
- "input": "⤦",
- "description": "Named entity: swarhk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2926"
- ]
- ]
- },
- {
- "input": "&swarr",
- "description": "Bad named entity: swarr without a semi-colon",
- "output": [
- [
- "Character",
- "&swarr"
- ]
- ]
- },
- {
- "input": "↙",
- "description": "Named entity: swarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2199"
- ]
- ]
- },
- {
- "input": "&swarrow",
- "description": "Bad named entity: swarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&swarrow"
- ]
- ]
- },
- {
- "input": "↙",
- "description": "Named entity: swarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2199"
- ]
- ]
- },
- {
- "input": "&swnwar",
- "description": "Bad named entity: swnwar without a semi-colon",
- "output": [
- [
- "Character",
- "&swnwar"
- ]
- ]
- },
- {
- "input": "⤪",
- "description": "Named entity: swnwar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u292a"
- ]
- ]
- },
- {
- "input": "ß",
- "description": "Named entity: szlig without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00df"
- ]
- ]
- },
- {
- "input": "ß",
- "description": "Named entity: szlig; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00df"
- ]
- ]
- },
- {
- "input": "&target",
- "description": "Bad named entity: target without a semi-colon",
- "output": [
- [
- "Character",
- "&target"
- ]
- ]
- },
- {
- "input": "⌖",
- "description": "Named entity: target; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2316"
- ]
- ]
- },
- {
- "input": "&tau",
- "description": "Bad named entity: tau without a semi-colon",
- "output": [
- [
- "Character",
- "&tau"
- ]
- ]
- },
- {
- "input": "τ",
- "description": "Named entity: tau; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c4"
- ]
- ]
- },
- {
- "input": "&tbrk",
- "description": "Bad named entity: tbrk without a semi-colon",
- "output": [
- [
- "Character",
- "&tbrk"
- ]
- ]
- },
- {
- "input": "⎴",
- "description": "Named entity: tbrk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23b4"
- ]
- ]
- },
- {
- "input": "&tcaron",
- "description": "Bad named entity: tcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&tcaron"
- ]
- ]
- },
- {
- "input": "ť",
- "description": "Named entity: tcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0165"
- ]
- ]
- },
- {
- "input": "&tcedil",
- "description": "Bad named entity: tcedil without a semi-colon",
- "output": [
- [
- "Character",
- "&tcedil"
- ]
- ]
- },
- {
- "input": "ţ",
- "description": "Named entity: tcedil; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0163"
- ]
- ]
- },
- {
- "input": "&tcy",
- "description": "Bad named entity: tcy without a semi-colon",
- "output": [
- [
- "Character",
- "&tcy"
- ]
- ]
- },
- {
- "input": "т",
- "description": "Named entity: tcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0442"
- ]
- ]
- },
- {
- "input": "&tdot",
- "description": "Bad named entity: tdot without a semi-colon",
- "output": [
- [
- "Character",
- "&tdot"
- ]
- ]
- },
- {
- "input": "⃛",
- "description": "Named entity: tdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u20db"
- ]
- ]
- },
- {
- "input": "&telrec",
- "description": "Bad named entity: telrec without a semi-colon",
- "output": [
- [
- "Character",
- "&telrec"
- ]
- ]
- },
- {
- "input": "⌕",
- "description": "Named entity: telrec; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2315"
- ]
- ]
- },
- {
- "input": "&tfr",
- "description": "Bad named entity: tfr without a semi-colon",
- "output": [
- [
- "Character",
- "&tfr"
- ]
- ]
- },
- {
- "input": "𝔱",
- "description": "Named entity: tfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd31"
- ]
- ]
- },
- {
- "input": "&there4",
- "description": "Bad named entity: there4 without a semi-colon",
- "output": [
- [
- "Character",
- "&there4"
- ]
- ]
- },
- {
- "input": "∴",
- "description": "Named entity: there4; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2234"
- ]
- ]
- },
- {
- "input": "&therefore",
- "description": "Bad named entity: therefore without a semi-colon",
- "output": [
- [
- "Character",
- "&therefore"
- ]
- ]
- },
- {
- "input": "∴",
- "description": "Named entity: therefore; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2234"
- ]
- ]
- },
- {
- "input": "&theta",
- "description": "Bad named entity: theta without a semi-colon",
- "output": [
- [
- "Character",
- "&theta"
- ]
- ]
- },
- {
- "input": "θ",
- "description": "Named entity: theta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b8"
- ]
- ]
- },
- {
- "input": "&thetasym",
- "description": "Bad named entity: thetasym without a semi-colon",
- "output": [
- [
- "Character",
- "&thetasym"
- ]
- ]
- },
- {
- "input": "ϑ",
- "description": "Named entity: thetasym; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d1"
- ]
- ]
- },
- {
- "input": "&thetav",
- "description": "Bad named entity: thetav without a semi-colon",
- "output": [
- [
- "Character",
- "&thetav"
- ]
- ]
- },
- {
- "input": "ϑ",
- "description": "Named entity: thetav; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d1"
- ]
- ]
- },
- {
- "input": "&thickapprox",
- "description": "Bad named entity: thickapprox without a semi-colon",
- "output": [
- [
- "Character",
- "&thickapprox"
- ]
- ]
- },
- {
- "input": "≈",
- "description": "Named entity: thickapprox; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2248"
- ]
- ]
- },
- {
- "input": "&thicksim",
- "description": "Bad named entity: thicksim without a semi-colon",
- "output": [
- [
- "Character",
- "&thicksim"
- ]
- ]
- },
- {
- "input": "∼",
- "description": "Named entity: thicksim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223c"
- ]
- ]
- },
- {
- "input": "&thinsp",
- "description": "Bad named entity: thinsp without a semi-colon",
- "output": [
- [
- "Character",
- "&thinsp"
- ]
- ]
- },
- {
- "input": " ",
- "description": "Named entity: thinsp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2009"
- ]
- ]
- },
- {
- "input": "&thkap",
- "description": "Bad named entity: thkap without a semi-colon",
- "output": [
- [
- "Character",
- "&thkap"
- ]
- ]
- },
- {
- "input": "≈",
- "description": "Named entity: thkap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2248"
- ]
- ]
- },
- {
- "input": "&thksim",
- "description": "Bad named entity: thksim without a semi-colon",
- "output": [
- [
- "Character",
- "&thksim"
- ]
- ]
- },
- {
- "input": "∼",
- "description": "Named entity: thksim; with a semi-colon",
- "output": [
- [
- "Character",
- "\u223c"
- ]
- ]
- },
- {
- "input": "þ",
- "description": "Named entity: thorn without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00fe"
- ]
- ]
- },
- {
- "input": "þ",
- "description": "Named entity: thorn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00fe"
- ]
- ]
- },
- {
- "input": "&tilde",
- "description": "Bad named entity: tilde without a semi-colon",
- "output": [
- [
- "Character",
- "&tilde"
- ]
- ]
- },
- {
- "input": "˜",
- "description": "Named entity: tilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u02dc"
- ]
- ]
- },
- {
- "input": "×",
- "description": "Named entity: times without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00d7"
- ]
- ]
- },
- {
- "input": "×",
- "description": "Named entity: times; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00d7"
- ]
- ]
- },
- {
- "input": "⊠",
- "description": "Named entity: timesb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a0"
- ]
- ]
- },
- {
- "input": "⨱",
- "description": "Named entity: timesbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a31"
- ]
- ]
- },
- {
- "input": "⨰",
- "description": "Named entity: timesd; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a30"
- ]
- ]
- },
- {
- "input": "&tint",
- "description": "Bad named entity: tint without a semi-colon",
- "output": [
- [
- "Character",
- "&tint"
- ]
- ]
- },
- {
- "input": "∭",
- "description": "Named entity: tint; with a semi-colon",
- "output": [
- [
- "Character",
- "\u222d"
- ]
- ]
- },
- {
- "input": "&toea",
- "description": "Bad named entity: toea without a semi-colon",
- "output": [
- [
- "Character",
- "&toea"
- ]
- ]
- },
- {
- "input": "⤨",
- "description": "Named entity: toea; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2928"
- ]
- ]
- },
- {
- "input": "&top",
- "description": "Bad named entity: top without a semi-colon",
- "output": [
- [
- "Character",
- "&top"
- ]
- ]
- },
- {
- "input": "⊤",
- "description": "Named entity: top; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a4"
- ]
- ]
- },
- {
- "input": "&topbot",
- "description": "Bad named entity: topbot without a semi-colon",
- "output": [
- [
- "Character",
- "&topbot"
- ]
- ]
- },
- {
- "input": "⌶",
- "description": "Named entity: topbot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2336"
- ]
- ]
- },
- {
- "input": "&topcir",
- "description": "Bad named entity: topcir without a semi-colon",
- "output": [
- [
- "Character",
- "&topcir"
- ]
- ]
- },
- {
- "input": "⫱",
- "description": "Named entity: topcir; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2af1"
- ]
- ]
- },
- {
- "input": "&topf",
- "description": "Bad named entity: topf without a semi-colon",
- "output": [
- [
- "Character",
- "&topf"
- ]
- ]
- },
- {
- "input": "𝕥",
- "description": "Named entity: topf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd65"
- ]
- ]
- },
- {
- "input": "&topfork",
- "description": "Bad named entity: topfork without a semi-colon",
- "output": [
- [
- "Character",
- "&topfork"
- ]
- ]
- },
- {
- "input": "⫚",
- "description": "Named entity: topfork; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ada"
- ]
- ]
- },
- {
- "input": "&tosa",
- "description": "Bad named entity: tosa without a semi-colon",
- "output": [
- [
- "Character",
- "&tosa"
- ]
- ]
- },
- {
- "input": "⤩",
- "description": "Named entity: tosa; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2929"
- ]
- ]
- },
- {
- "input": "&tprime",
- "description": "Bad named entity: tprime without a semi-colon",
- "output": [
- [
- "Character",
- "&tprime"
- ]
- ]
- },
- {
- "input": "‴",
- "description": "Named entity: tprime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2034"
- ]
- ]
- },
- {
- "input": "&trade",
- "description": "Bad named entity: trade without a semi-colon",
- "output": [
- [
- "Character",
- "&trade"
- ]
- ]
- },
- {
- "input": "™",
- "description": "Named entity: trade; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2122"
- ]
- ]
- },
- {
- "input": "&triangle",
- "description": "Bad named entity: triangle without a semi-colon",
- "output": [
- [
- "Character",
- "&triangle"
- ]
- ]
- },
- {
- "input": "▵",
- "description": "Named entity: triangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b5"
- ]
- ]
- },
- {
- "input": "&triangledown",
- "description": "Bad named entity: triangledown without a semi-colon",
- "output": [
- [
- "Character",
- "&triangledown"
- ]
- ]
- },
- {
- "input": "▿",
- "description": "Named entity: triangledown; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25bf"
- ]
- ]
- },
- {
- "input": "&triangleleft",
- "description": "Bad named entity: triangleleft without a semi-colon",
- "output": [
- [
- "Character",
- "&triangleleft"
- ]
- ]
- },
- {
- "input": "◃",
- "description": "Named entity: triangleleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25c3"
- ]
- ]
- },
- {
- "input": "&trianglelefteq",
- "description": "Bad named entity: trianglelefteq without a semi-colon",
- "output": [
- [
- "Character",
- "&trianglelefteq"
- ]
- ]
- },
- {
- "input": "⊴",
- "description": "Named entity: trianglelefteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b4"
- ]
- ]
- },
- {
- "input": "&triangleq",
- "description": "Bad named entity: triangleq without a semi-colon",
- "output": [
- [
- "Character",
- "&triangleq"
- ]
- ]
- },
- {
- "input": "≜",
- "description": "Named entity: triangleq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u225c"
- ]
- ]
- },
- {
- "input": "&triangleright",
- "description": "Bad named entity: triangleright without a semi-colon",
- "output": [
- [
- "Character",
- "&triangleright"
- ]
- ]
- },
- {
- "input": "▹",
- "description": "Named entity: triangleright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b9"
- ]
- ]
- },
- {
- "input": "&trianglerighteq",
- "description": "Bad named entity: trianglerighteq without a semi-colon",
- "output": [
- [
- "Character",
- "&trianglerighteq"
- ]
- ]
- },
- {
- "input": "⊵",
- "description": "Named entity: trianglerighteq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b5"
- ]
- ]
- },
- {
- "input": "&tridot",
- "description": "Bad named entity: tridot without a semi-colon",
- "output": [
- [
- "Character",
- "&tridot"
- ]
- ]
- },
- {
- "input": "◬",
- "description": "Named entity: tridot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25ec"
- ]
- ]
- },
- {
- "input": "&trie",
- "description": "Bad named entity: trie without a semi-colon",
- "output": [
- [
- "Character",
- "&trie"
- ]
- ]
- },
- {
- "input": "≜",
- "description": "Named entity: trie; with a semi-colon",
- "output": [
- [
- "Character",
- "\u225c"
- ]
- ]
- },
- {
- "input": "&triminus",
- "description": "Bad named entity: triminus without a semi-colon",
- "output": [
- [
- "Character",
- "&triminus"
- ]
- ]
- },
- {
- "input": "⨺",
- "description": "Named entity: triminus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a3a"
- ]
- ]
- },
- {
- "input": "&triplus",
- "description": "Bad named entity: triplus without a semi-colon",
- "output": [
- [
- "Character",
- "&triplus"
- ]
- ]
- },
- {
- "input": "⨹",
- "description": "Named entity: triplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a39"
- ]
- ]
- },
- {
- "input": "&trisb",
- "description": "Bad named entity: trisb without a semi-colon",
- "output": [
- [
- "Character",
- "&trisb"
- ]
- ]
- },
- {
- "input": "⧍",
- "description": "Named entity: trisb; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29cd"
- ]
- ]
- },
- {
- "input": "&tritime",
- "description": "Bad named entity: tritime without a semi-colon",
- "output": [
- [
- "Character",
- "&tritime"
- ]
- ]
- },
- {
- "input": "⨻",
- "description": "Named entity: tritime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a3b"
- ]
- ]
- },
- {
- "input": "&trpezium",
- "description": "Bad named entity: trpezium without a semi-colon",
- "output": [
- [
- "Character",
- "&trpezium"
- ]
- ]
- },
- {
- "input": "⏢",
- "description": "Named entity: trpezium; with a semi-colon",
- "output": [
- [
- "Character",
- "\u23e2"
- ]
- ]
- },
- {
- "input": "&tscr",
- "description": "Bad named entity: tscr without a semi-colon",
- "output": [
- [
- "Character",
- "&tscr"
- ]
- ]
- },
- {
- "input": "𝓉",
- "description": "Named entity: tscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcc9"
- ]
- ]
- },
- {
- "input": "&tscy",
- "description": "Bad named entity: tscy without a semi-colon",
- "output": [
- [
- "Character",
- "&tscy"
- ]
- ]
- },
- {
- "input": "ц",
- "description": "Named entity: tscy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0446"
- ]
- ]
- },
- {
- "input": "&tshcy",
- "description": "Bad named entity: tshcy without a semi-colon",
- "output": [
- [
- "Character",
- "&tshcy"
- ]
- ]
- },
- {
- "input": "ћ",
- "description": "Named entity: tshcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u045b"
- ]
- ]
- },
- {
- "input": "&tstrok",
- "description": "Bad named entity: tstrok without a semi-colon",
- "output": [
- [
- "Character",
- "&tstrok"
- ]
- ]
- },
- {
- "input": "ŧ",
- "description": "Named entity: tstrok; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0167"
- ]
- ]
- },
- {
- "input": "&twixt",
- "description": "Bad named entity: twixt without a semi-colon",
- "output": [
- [
- "Character",
- "&twixt"
- ]
- ]
- },
- {
- "input": "≬",
- "description": "Named entity: twixt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u226c"
- ]
- ]
- },
- {
- "input": "&twoheadleftarrow",
- "description": "Bad named entity: twoheadleftarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&twoheadleftarrow"
- ]
- ]
- },
- {
- "input": "↞",
- "description": "Named entity: twoheadleftarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u219e"
- ]
- ]
- },
- {
- "input": "&twoheadrightarrow",
- "description": "Bad named entity: twoheadrightarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&twoheadrightarrow"
- ]
- ]
- },
- {
- "input": "↠",
- "description": "Named entity: twoheadrightarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21a0"
- ]
- ]
- },
- {
- "input": "&uArr",
- "description": "Bad named entity: uArr without a semi-colon",
- "output": [
- [
- "Character",
- "&uArr"
- ]
- ]
- },
- {
- "input": "⇑",
- "description": "Named entity: uArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d1"
- ]
- ]
- },
- {
- "input": "&uHar",
- "description": "Bad named entity: uHar without a semi-colon",
- "output": [
- [
- "Character",
- "&uHar"
- ]
- ]
- },
- {
- "input": "⥣",
- "description": "Named entity: uHar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2963"
- ]
- ]
- },
- {
- "input": "ú",
- "description": "Named entity: uacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00fa"
- ]
- ]
- },
- {
- "input": "ú",
- "description": "Named entity: uacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00fa"
- ]
- ]
- },
- {
- "input": "&uarr",
- "description": "Bad named entity: uarr without a semi-colon",
- "output": [
- [
- "Character",
- "&uarr"
- ]
- ]
- },
- {
- "input": "↑",
- "description": "Named entity: uarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2191"
- ]
- ]
- },
- {
- "input": "&ubrcy",
- "description": "Bad named entity: ubrcy without a semi-colon",
- "output": [
- [
- "Character",
- "&ubrcy"
- ]
- ]
- },
- {
- "input": "ў",
- "description": "Named entity: ubrcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u045e"
- ]
- ]
- },
- {
- "input": "&ubreve",
- "description": "Bad named entity: ubreve without a semi-colon",
- "output": [
- [
- "Character",
- "&ubreve"
- ]
- ]
- },
- {
- "input": "ŭ",
- "description": "Named entity: ubreve; with a semi-colon",
- "output": [
- [
- "Character",
- "\u016d"
- ]
- ]
- },
- {
- "input": "û",
- "description": "Named entity: ucirc without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00fb"
- ]
- ]
- },
- {
- "input": "û",
- "description": "Named entity: ucirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00fb"
- ]
- ]
- },
- {
- "input": "&ucy",
- "description": "Bad named entity: ucy without a semi-colon",
- "output": [
- [
- "Character",
- "&ucy"
- ]
- ]
- },
- {
- "input": "у",
- "description": "Named entity: ucy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0443"
- ]
- ]
- },
- {
- "input": "&udarr",
- "description": "Bad named entity: udarr without a semi-colon",
- "output": [
- [
- "Character",
- "&udarr"
- ]
- ]
- },
- {
- "input": "⇅",
- "description": "Named entity: udarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c5"
- ]
- ]
- },
- {
- "input": "&udblac",
- "description": "Bad named entity: udblac without a semi-colon",
- "output": [
- [
- "Character",
- "&udblac"
- ]
- ]
- },
- {
- "input": "ű",
- "description": "Named entity: udblac; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0171"
- ]
- ]
- },
- {
- "input": "&udhar",
- "description": "Bad named entity: udhar without a semi-colon",
- "output": [
- [
- "Character",
- "&udhar"
- ]
- ]
- },
- {
- "input": "⥮",
- "description": "Named entity: udhar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u296e"
- ]
- ]
- },
- {
- "input": "&ufisht",
- "description": "Bad named entity: ufisht without a semi-colon",
- "output": [
- [
- "Character",
- "&ufisht"
- ]
- ]
- },
- {
- "input": "⥾",
- "description": "Named entity: ufisht; with a semi-colon",
- "output": [
- [
- "Character",
- "\u297e"
- ]
- ]
- },
- {
- "input": "&ufr",
- "description": "Bad named entity: ufr without a semi-colon",
- "output": [
- [
- "Character",
- "&ufr"
- ]
- ]
- },
- {
- "input": "𝔲",
- "description": "Named entity: ufr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd32"
- ]
- ]
- },
- {
- "input": "ù",
- "description": "Named entity: ugrave without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00f9"
- ]
- ]
- },
- {
- "input": "ù",
- "description": "Named entity: ugrave; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00f9"
- ]
- ]
- },
- {
- "input": "&uharl",
- "description": "Bad named entity: uharl without a semi-colon",
- "output": [
- [
- "Character",
- "&uharl"
- ]
- ]
- },
- {
- "input": "↿",
- "description": "Named entity: uharl; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bf"
- ]
- ]
- },
- {
- "input": "&uharr",
- "description": "Bad named entity: uharr without a semi-colon",
- "output": [
- [
- "Character",
- "&uharr"
- ]
- ]
- },
- {
- "input": "↾",
- "description": "Named entity: uharr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21be"
- ]
- ]
- },
- {
- "input": "&uhblk",
- "description": "Bad named entity: uhblk without a semi-colon",
- "output": [
- [
- "Character",
- "&uhblk"
- ]
- ]
- },
- {
- "input": "▀",
- "description": "Named entity: uhblk; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2580"
- ]
- ]
- },
- {
- "input": "&ulcorn",
- "description": "Bad named entity: ulcorn without a semi-colon",
- "output": [
- [
- "Character",
- "&ulcorn"
- ]
- ]
- },
- {
- "input": "⌜",
- "description": "Named entity: ulcorn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u231c"
- ]
- ]
- },
- {
- "input": "&ulcorner",
- "description": "Bad named entity: ulcorner without a semi-colon",
- "output": [
- [
- "Character",
- "&ulcorner"
- ]
- ]
- },
- {
- "input": "⌜",
- "description": "Named entity: ulcorner; with a semi-colon",
- "output": [
- [
- "Character",
- "\u231c"
- ]
- ]
- },
- {
- "input": "&ulcrop",
- "description": "Bad named entity: ulcrop without a semi-colon",
- "output": [
- [
- "Character",
- "&ulcrop"
- ]
- ]
- },
- {
- "input": "⌏",
- "description": "Named entity: ulcrop; with a semi-colon",
- "output": [
- [
- "Character",
- "\u230f"
- ]
- ]
- },
- {
- "input": "&ultri",
- "description": "Bad named entity: ultri without a semi-colon",
- "output": [
- [
- "Character",
- "&ultri"
- ]
- ]
- },
- {
- "input": "◸",
- "description": "Named entity: ultri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25f8"
- ]
- ]
- },
- {
- "input": "&umacr",
- "description": "Bad named entity: umacr without a semi-colon",
- "output": [
- [
- "Character",
- "&umacr"
- ]
- ]
- },
- {
- "input": "ū",
- "description": "Named entity: umacr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u016b"
- ]
- ]
- },
- {
- "input": "¨",
- "description": "Named entity: uml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a8"
- ]
- ]
- },
- {
- "input": "¨",
- "description": "Named entity: uml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a8"
- ]
- ]
- },
- {
- "input": "&uogon",
- "description": "Bad named entity: uogon without a semi-colon",
- "output": [
- [
- "Character",
- "&uogon"
- ]
- ]
- },
- {
- "input": "ų",
- "description": "Named entity: uogon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0173"
- ]
- ]
- },
- {
- "input": "&uopf",
- "description": "Bad named entity: uopf without a semi-colon",
- "output": [
- [
- "Character",
- "&uopf"
- ]
- ]
- },
- {
- "input": "𝕦",
- "description": "Named entity: uopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd66"
- ]
- ]
- },
- {
- "input": "&uparrow",
- "description": "Bad named entity: uparrow without a semi-colon",
- "output": [
- [
- "Character",
- "&uparrow"
- ]
- ]
- },
- {
- "input": "↑",
- "description": "Named entity: uparrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2191"
- ]
- ]
- },
- {
- "input": "&updownarrow",
- "description": "Bad named entity: updownarrow without a semi-colon",
- "output": [
- [
- "Character",
- "&updownarrow"
- ]
- ]
- },
- {
- "input": "↕",
- "description": "Named entity: updownarrow; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2195"
- ]
- ]
- },
- {
- "input": "&upharpoonleft",
- "description": "Bad named entity: upharpoonleft without a semi-colon",
- "output": [
- [
- "Character",
- "&upharpoonleft"
- ]
- ]
- },
- {
- "input": "↿",
- "description": "Named entity: upharpoonleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21bf"
- ]
- ]
- },
- {
- "input": "&upharpoonright",
- "description": "Bad named entity: upharpoonright without a semi-colon",
- "output": [
- [
- "Character",
- "&upharpoonright"
- ]
- ]
- },
- {
- "input": "↾",
- "description": "Named entity: upharpoonright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21be"
- ]
- ]
- },
- {
- "input": "&uplus",
- "description": "Bad named entity: uplus without a semi-colon",
- "output": [
- [
- "Character",
- "&uplus"
- ]
- ]
- },
- {
- "input": "⊎",
- "description": "Named entity: uplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228e"
- ]
- ]
- },
- {
- "input": "&upsi",
- "description": "Bad named entity: upsi without a semi-colon",
- "output": [
- [
- "Character",
- "&upsi"
- ]
- ]
- },
- {
- "input": "υ",
- "description": "Named entity: upsi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c5"
- ]
- ]
- },
- {
- "input": "&upsih",
- "description": "Bad named entity: upsih without a semi-colon",
- "output": [
- [
- "Character",
- "&upsih"
- ]
- ]
- },
- {
- "input": "ϒ",
- "description": "Named entity: upsih; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d2"
- ]
- ]
- },
- {
- "input": "&upsilon",
- "description": "Bad named entity: upsilon without a semi-colon",
- "output": [
- [
- "Character",
- "&upsilon"
- ]
- ]
- },
- {
- "input": "υ",
- "description": "Named entity: upsilon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c5"
- ]
- ]
- },
- {
- "input": "&upuparrows",
- "description": "Bad named entity: upuparrows without a semi-colon",
- "output": [
- [
- "Character",
- "&upuparrows"
- ]
- ]
- },
- {
- "input": "⇈",
- "description": "Named entity: upuparrows; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c8"
- ]
- ]
- },
- {
- "input": "&urcorn",
- "description": "Bad named entity: urcorn without a semi-colon",
- "output": [
- [
- "Character",
- "&urcorn"
- ]
- ]
- },
- {
- "input": "⌝",
- "description": "Named entity: urcorn; with a semi-colon",
- "output": [
- [
- "Character",
- "\u231d"
- ]
- ]
- },
- {
- "input": "&urcorner",
- "description": "Bad named entity: urcorner without a semi-colon",
- "output": [
- [
- "Character",
- "&urcorner"
- ]
- ]
- },
- {
- "input": "⌝",
- "description": "Named entity: urcorner; with a semi-colon",
- "output": [
- [
- "Character",
- "\u231d"
- ]
- ]
- },
- {
- "input": "&urcrop",
- "description": "Bad named entity: urcrop without a semi-colon",
- "output": [
- [
- "Character",
- "&urcrop"
- ]
- ]
- },
- {
- "input": "⌎",
- "description": "Named entity: urcrop; with a semi-colon",
- "output": [
- [
- "Character",
- "\u230e"
- ]
- ]
- },
- {
- "input": "&uring",
- "description": "Bad named entity: uring without a semi-colon",
- "output": [
- [
- "Character",
- "&uring"
- ]
- ]
- },
- {
- "input": "ů",
- "description": "Named entity: uring; with a semi-colon",
- "output": [
- [
- "Character",
- "\u016f"
- ]
- ]
- },
- {
- "input": "&urtri",
- "description": "Bad named entity: urtri without a semi-colon",
- "output": [
- [
- "Character",
- "&urtri"
- ]
- ]
- },
- {
- "input": "◹",
- "description": "Named entity: urtri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25f9"
- ]
- ]
- },
- {
- "input": "&uscr",
- "description": "Bad named entity: uscr without a semi-colon",
- "output": [
- [
- "Character",
- "&uscr"
- ]
- ]
- },
- {
- "input": "𝓊",
- "description": "Named entity: uscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcca"
- ]
- ]
- },
- {
- "input": "&utdot",
- "description": "Bad named entity: utdot without a semi-colon",
- "output": [
- [
- "Character",
- "&utdot"
- ]
- ]
- },
- {
- "input": "⋰",
- "description": "Named entity: utdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22f0"
- ]
- ]
- },
- {
- "input": "&utilde",
- "description": "Bad named entity: utilde without a semi-colon",
- "output": [
- [
- "Character",
- "&utilde"
- ]
- ]
- },
- {
- "input": "ũ",
- "description": "Named entity: utilde; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0169"
- ]
- ]
- },
- {
- "input": "&utri",
- "description": "Bad named entity: utri without a semi-colon",
- "output": [
- [
- "Character",
- "&utri"
- ]
- ]
- },
- {
- "input": "▵",
- "description": "Named entity: utri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b5"
- ]
- ]
- },
- {
- "input": "&utrif",
- "description": "Bad named entity: utrif without a semi-colon",
- "output": [
- [
- "Character",
- "&utrif"
- ]
- ]
- },
- {
- "input": "▴",
- "description": "Named entity: utrif; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b4"
- ]
- ]
- },
- {
- "input": "&uuarr",
- "description": "Bad named entity: uuarr without a semi-colon",
- "output": [
- [
- "Character",
- "&uuarr"
- ]
- ]
- },
- {
- "input": "⇈",
- "description": "Named entity: uuarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21c8"
- ]
- ]
- },
- {
- "input": "ü",
- "description": "Named entity: uuml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00fc"
- ]
- ]
- },
- {
- "input": "ü",
- "description": "Named entity: uuml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00fc"
- ]
- ]
- },
- {
- "input": "&uwangle",
- "description": "Bad named entity: uwangle without a semi-colon",
- "output": [
- [
- "Character",
- "&uwangle"
- ]
- ]
- },
- {
- "input": "⦧",
- "description": "Named entity: uwangle; with a semi-colon",
- "output": [
- [
- "Character",
- "\u29a7"
- ]
- ]
- },
- {
- "input": "&vArr",
- "description": "Bad named entity: vArr without a semi-colon",
- "output": [
- [
- "Character",
- "&vArr"
- ]
- ]
- },
- {
- "input": "⇕",
- "description": "Named entity: vArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21d5"
- ]
- ]
- },
- {
- "input": "&vBar",
- "description": "Bad named entity: vBar without a semi-colon",
- "output": [
- [
- "Character",
- "&vBar"
- ]
- ]
- },
- {
- "input": "⫨",
- "description": "Named entity: vBar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ae8"
- ]
- ]
- },
- {
- "input": "&vBarv",
- "description": "Bad named entity: vBarv without a semi-colon",
- "output": [
- [
- "Character",
- "&vBarv"
- ]
- ]
- },
- {
- "input": "⫩",
- "description": "Named entity: vBarv; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2ae9"
- ]
- ]
- },
- {
- "input": "&vDash",
- "description": "Bad named entity: vDash without a semi-colon",
- "output": [
- [
- "Character",
- "&vDash"
- ]
- ]
- },
- {
- "input": "⊨",
- "description": "Named entity: vDash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a8"
- ]
- ]
- },
- {
- "input": "&vangrt",
- "description": "Bad named entity: vangrt without a semi-colon",
- "output": [
- [
- "Character",
- "&vangrt"
- ]
- ]
- },
- {
- "input": "⦜",
- "description": "Named entity: vangrt; with a semi-colon",
- "output": [
- [
- "Character",
- "\u299c"
- ]
- ]
- },
- {
- "input": "&varepsilon",
- "description": "Bad named entity: varepsilon without a semi-colon",
- "output": [
- [
- "Character",
- "&varepsilon"
- ]
- ]
- },
- {
- "input": "ϵ",
- "description": "Named entity: varepsilon; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f5"
- ]
- ]
- },
- {
- "input": "&varkappa",
- "description": "Bad named entity: varkappa without a semi-colon",
- "output": [
- [
- "Character",
- "&varkappa"
- ]
- ]
- },
- {
- "input": "ϰ",
- "description": "Named entity: varkappa; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f0"
- ]
- ]
- },
- {
- "input": "&varnothing",
- "description": "Bad named entity: varnothing without a semi-colon",
- "output": [
- [
- "Character",
- "&varnothing"
- ]
- ]
- },
- {
- "input": "∅",
- "description": "Named entity: varnothing; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2205"
- ]
- ]
- },
- {
- "input": "&varphi",
- "description": "Bad named entity: varphi without a semi-colon",
- "output": [
- [
- "Character",
- "&varphi"
- ]
- ]
- },
- {
- "input": "ϕ",
- "description": "Named entity: varphi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d5"
- ]
- ]
- },
- {
- "input": "&varpi",
- "description": "Bad named entity: varpi without a semi-colon",
- "output": [
- [
- "Character",
- "&varpi"
- ]
- ]
- },
- {
- "input": "ϖ",
- "description": "Named entity: varpi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d6"
- ]
- ]
- },
- {
- "input": "&varpropto",
- "description": "Bad named entity: varpropto without a semi-colon",
- "output": [
- [
- "Character",
- "&varpropto"
- ]
- ]
- },
- {
- "input": "∝",
- "description": "Named entity: varpropto; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221d"
- ]
- ]
- },
- {
- "input": "&varr",
- "description": "Bad named entity: varr without a semi-colon",
- "output": [
- [
- "Character",
- "&varr"
- ]
- ]
- },
- {
- "input": "↕",
- "description": "Named entity: varr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2195"
- ]
- ]
- },
- {
- "input": "&varrho",
- "description": "Bad named entity: varrho without a semi-colon",
- "output": [
- [
- "Character",
- "&varrho"
- ]
- ]
- },
- {
- "input": "ϱ",
- "description": "Named entity: varrho; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03f1"
- ]
- ]
- },
- {
- "input": "&varsigma",
- "description": "Bad named entity: varsigma without a semi-colon",
- "output": [
- [
- "Character",
- "&varsigma"
- ]
- ]
- },
- {
- "input": "ς",
- "description": "Named entity: varsigma; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03c2"
- ]
- ]
- },
- {
- "input": "&varsubsetneq",
- "description": "Bad named entity: varsubsetneq without a semi-colon",
- "output": [
- [
- "Character",
- "&varsubsetneq"
- ]
- ]
- },
- {
- "input": "⊊︀",
- "description": "Named entity: varsubsetneq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228a\ufe00"
- ]
- ]
- },
- {
- "input": "&varsubsetneqq",
- "description": "Bad named entity: varsubsetneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&varsubsetneqq"
- ]
- ]
- },
- {
- "input": "⫋︀",
- "description": "Named entity: varsubsetneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acb\ufe00"
- ]
- ]
- },
- {
- "input": "&varsupsetneq",
- "description": "Bad named entity: varsupsetneq without a semi-colon",
- "output": [
- [
- "Character",
- "&varsupsetneq"
- ]
- ]
- },
- {
- "input": "⊋︀",
- "description": "Named entity: varsupsetneq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228b\ufe00"
- ]
- ]
- },
- {
- "input": "&varsupsetneqq",
- "description": "Bad named entity: varsupsetneqq without a semi-colon",
- "output": [
- [
- "Character",
- "&varsupsetneqq"
- ]
- ]
- },
- {
- "input": "⫌︀",
- "description": "Named entity: varsupsetneqq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acc\ufe00"
- ]
- ]
- },
- {
- "input": "&vartheta",
- "description": "Bad named entity: vartheta without a semi-colon",
- "output": [
- [
- "Character",
- "&vartheta"
- ]
- ]
- },
- {
- "input": "ϑ",
- "description": "Named entity: vartheta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03d1"
- ]
- ]
- },
- {
- "input": "&vartriangleleft",
- "description": "Bad named entity: vartriangleleft without a semi-colon",
- "output": [
- [
- "Character",
- "&vartriangleleft"
- ]
- ]
- },
- {
- "input": "⊲",
- "description": "Named entity: vartriangleleft; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b2"
- ]
- ]
- },
- {
- "input": "&vartriangleright",
- "description": "Bad named entity: vartriangleright without a semi-colon",
- "output": [
- [
- "Character",
- "&vartriangleright"
- ]
- ]
- },
- {
- "input": "⊳",
- "description": "Named entity: vartriangleright; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b3"
- ]
- ]
- },
- {
- "input": "&vcy",
- "description": "Bad named entity: vcy without a semi-colon",
- "output": [
- [
- "Character",
- "&vcy"
- ]
- ]
- },
- {
- "input": "в",
- "description": "Named entity: vcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0432"
- ]
- ]
- },
- {
- "input": "&vdash",
- "description": "Bad named entity: vdash without a semi-colon",
- "output": [
- [
- "Character",
- "&vdash"
- ]
- ]
- },
- {
- "input": "⊢",
- "description": "Named entity: vdash; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22a2"
- ]
- ]
- },
- {
- "input": "&vee",
- "description": "Bad named entity: vee without a semi-colon",
- "output": [
- [
- "Character",
- "&vee"
- ]
- ]
- },
- {
- "input": "∨",
- "description": "Named entity: vee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2228"
- ]
- ]
- },
- {
- "input": "&veebar",
- "description": "Bad named entity: veebar without a semi-colon",
- "output": [
- [
- "Character",
- "&veebar"
- ]
- ]
- },
- {
- "input": "⊻",
- "description": "Named entity: veebar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22bb"
- ]
- ]
- },
- {
- "input": "&veeeq",
- "description": "Bad named entity: veeeq without a semi-colon",
- "output": [
- [
- "Character",
- "&veeeq"
- ]
- ]
- },
- {
- "input": "≚",
- "description": "Named entity: veeeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u225a"
- ]
- ]
- },
- {
- "input": "&vellip",
- "description": "Bad named entity: vellip without a semi-colon",
- "output": [
- [
- "Character",
- "&vellip"
- ]
- ]
- },
- {
- "input": "⋮",
- "description": "Named entity: vellip; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22ee"
- ]
- ]
- },
- {
- "input": "&verbar",
- "description": "Bad named entity: verbar without a semi-colon",
- "output": [
- [
- "Character",
- "&verbar"
- ]
- ]
- },
- {
- "input": "|",
- "description": "Named entity: verbar; with a semi-colon",
- "output": [
- [
- "Character",
- "|"
- ]
- ]
- },
- {
- "input": "&vert",
- "description": "Bad named entity: vert without a semi-colon",
- "output": [
- [
- "Character",
- "&vert"
- ]
- ]
- },
- {
- "input": "|",
- "description": "Named entity: vert; with a semi-colon",
- "output": [
- [
- "Character",
- "|"
- ]
- ]
- },
- {
- "input": "&vfr",
- "description": "Bad named entity: vfr without a semi-colon",
- "output": [
- [
- "Character",
- "&vfr"
- ]
- ]
- },
- {
- "input": "𝔳",
- "description": "Named entity: vfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd33"
- ]
- ]
- },
- {
- "input": "&vltri",
- "description": "Bad named entity: vltri without a semi-colon",
- "output": [
- [
- "Character",
- "&vltri"
- ]
- ]
- },
- {
- "input": "⊲",
- "description": "Named entity: vltri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b2"
- ]
- ]
- },
- {
- "input": "&vnsub",
- "description": "Bad named entity: vnsub without a semi-colon",
- "output": [
- [
- "Character",
- "&vnsub"
- ]
- ]
- },
- {
- "input": "⊂⃒",
- "description": "Named entity: vnsub; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2282\u20d2"
- ]
- ]
- },
- {
- "input": "&vnsup",
- "description": "Bad named entity: vnsup without a semi-colon",
- "output": [
- [
- "Character",
- "&vnsup"
- ]
- ]
- },
- {
- "input": "⊃⃒",
- "description": "Named entity: vnsup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2283\u20d2"
- ]
- ]
- },
- {
- "input": "&vopf",
- "description": "Bad named entity: vopf without a semi-colon",
- "output": [
- [
- "Character",
- "&vopf"
- ]
- ]
- },
- {
- "input": "𝕧",
- "description": "Named entity: vopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd67"
- ]
- ]
- },
- {
- "input": "&vprop",
- "description": "Bad named entity: vprop without a semi-colon",
- "output": [
- [
- "Character",
- "&vprop"
- ]
- ]
- },
- {
- "input": "∝",
- "description": "Named entity: vprop; with a semi-colon",
- "output": [
- [
- "Character",
- "\u221d"
- ]
- ]
- },
- {
- "input": "&vrtri",
- "description": "Bad named entity: vrtri without a semi-colon",
- "output": [
- [
- "Character",
- "&vrtri"
- ]
- ]
- },
- {
- "input": "⊳",
- "description": "Named entity: vrtri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22b3"
- ]
- ]
- },
- {
- "input": "&vscr",
- "description": "Bad named entity: vscr without a semi-colon",
- "output": [
- [
- "Character",
- "&vscr"
- ]
- ]
- },
- {
- "input": "𝓋",
- "description": "Named entity: vscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udccb"
- ]
- ]
- },
- {
- "input": "&vsubnE",
- "description": "Bad named entity: vsubnE without a semi-colon",
- "output": [
- [
- "Character",
- "&vsubnE"
- ]
- ]
- },
- {
- "input": "⫋︀",
- "description": "Named entity: vsubnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acb\ufe00"
- ]
- ]
- },
- {
- "input": "&vsubne",
- "description": "Bad named entity: vsubne without a semi-colon",
- "output": [
- [
- "Character",
- "&vsubne"
- ]
- ]
- },
- {
- "input": "⊊︀",
- "description": "Named entity: vsubne; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228a\ufe00"
- ]
- ]
- },
- {
- "input": "&vsupnE",
- "description": "Bad named entity: vsupnE without a semi-colon",
- "output": [
- [
- "Character",
- "&vsupnE"
- ]
- ]
- },
- {
- "input": "⫌︀",
- "description": "Named entity: vsupnE; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2acc\ufe00"
- ]
- ]
- },
- {
- "input": "&vsupne",
- "description": "Bad named entity: vsupne without a semi-colon",
- "output": [
- [
- "Character",
- "&vsupne"
- ]
- ]
- },
- {
- "input": "⊋︀",
- "description": "Named entity: vsupne; with a semi-colon",
- "output": [
- [
- "Character",
- "\u228b\ufe00"
- ]
- ]
- },
- {
- "input": "&vzigzag",
- "description": "Bad named entity: vzigzag without a semi-colon",
- "output": [
- [
- "Character",
- "&vzigzag"
- ]
- ]
- },
- {
- "input": "⦚",
- "description": "Named entity: vzigzag; with a semi-colon",
- "output": [
- [
- "Character",
- "\u299a"
- ]
- ]
- },
- {
- "input": "&wcirc",
- "description": "Bad named entity: wcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&wcirc"
- ]
- ]
- },
- {
- "input": "ŵ",
- "description": "Named entity: wcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0175"
- ]
- ]
- },
- {
- "input": "&wedbar",
- "description": "Bad named entity: wedbar without a semi-colon",
- "output": [
- [
- "Character",
- "&wedbar"
- ]
- ]
- },
- {
- "input": "⩟",
- "description": "Named entity: wedbar; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a5f"
- ]
- ]
- },
- {
- "input": "&wedge",
- "description": "Bad named entity: wedge without a semi-colon",
- "output": [
- [
- "Character",
- "&wedge"
- ]
- ]
- },
- {
- "input": "∧",
- "description": "Named entity: wedge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2227"
- ]
- ]
- },
- {
- "input": "&wedgeq",
- "description": "Bad named entity: wedgeq without a semi-colon",
- "output": [
- [
- "Character",
- "&wedgeq"
- ]
- ]
- },
- {
- "input": "≙",
- "description": "Named entity: wedgeq; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2259"
- ]
- ]
- },
- {
- "input": "&weierp",
- "description": "Bad named entity: weierp without a semi-colon",
- "output": [
- [
- "Character",
- "&weierp"
- ]
- ]
- },
- {
- "input": "℘",
- "description": "Named entity: weierp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2118"
- ]
- ]
- },
- {
- "input": "&wfr",
- "description": "Bad named entity: wfr without a semi-colon",
- "output": [
- [
- "Character",
- "&wfr"
- ]
- ]
- },
- {
- "input": "𝔴",
- "description": "Named entity: wfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd34"
- ]
- ]
- },
- {
- "input": "&wopf",
- "description": "Bad named entity: wopf without a semi-colon",
- "output": [
- [
- "Character",
- "&wopf"
- ]
- ]
- },
- {
- "input": "𝕨",
- "description": "Named entity: wopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd68"
- ]
- ]
- },
- {
- "input": "&wp",
- "description": "Bad named entity: wp without a semi-colon",
- "output": [
- [
- "Character",
- "&wp"
- ]
- ]
- },
- {
- "input": "℘",
- "description": "Named entity: wp; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2118"
- ]
- ]
- },
- {
- "input": "&wr",
- "description": "Bad named entity: wr without a semi-colon",
- "output": [
- [
- "Character",
- "&wr"
- ]
- ]
- },
- {
- "input": "≀",
- "description": "Named entity: wr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2240"
- ]
- ]
- },
- {
- "input": "&wreath",
- "description": "Bad named entity: wreath without a semi-colon",
- "output": [
- [
- "Character",
- "&wreath"
- ]
- ]
- },
- {
- "input": "≀",
- "description": "Named entity: wreath; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2240"
- ]
- ]
- },
- {
- "input": "&wscr",
- "description": "Bad named entity: wscr without a semi-colon",
- "output": [
- [
- "Character",
- "&wscr"
- ]
- ]
- },
- {
- "input": "𝓌",
- "description": "Named entity: wscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udccc"
- ]
- ]
- },
- {
- "input": "&xcap",
- "description": "Bad named entity: xcap without a semi-colon",
- "output": [
- [
- "Character",
- "&xcap"
- ]
- ]
- },
- {
- "input": "⋂",
- "description": "Named entity: xcap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c2"
- ]
- ]
- },
- {
- "input": "&xcirc",
- "description": "Bad named entity: xcirc without a semi-colon",
- "output": [
- [
- "Character",
- "&xcirc"
- ]
- ]
- },
- {
- "input": "◯",
- "description": "Named entity: xcirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25ef"
- ]
- ]
- },
- {
- "input": "&xcup",
- "description": "Bad named entity: xcup without a semi-colon",
- "output": [
- [
- "Character",
- "&xcup"
- ]
- ]
- },
- {
- "input": "⋃",
- "description": "Named entity: xcup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c3"
- ]
- ]
- },
- {
- "input": "&xdtri",
- "description": "Bad named entity: xdtri without a semi-colon",
- "output": [
- [
- "Character",
- "&xdtri"
- ]
- ]
- },
- {
- "input": "▽",
- "description": "Named entity: xdtri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25bd"
- ]
- ]
- },
- {
- "input": "&xfr",
- "description": "Bad named entity: xfr without a semi-colon",
- "output": [
- [
- "Character",
- "&xfr"
- ]
- ]
- },
- {
- "input": "𝔵",
- "description": "Named entity: xfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd35"
- ]
- ]
- },
- {
- "input": "&xhArr",
- "description": "Bad named entity: xhArr without a semi-colon",
- "output": [
- [
- "Character",
- "&xhArr"
- ]
- ]
- },
- {
- "input": "⟺",
- "description": "Named entity: xhArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27fa"
- ]
- ]
- },
- {
- "input": "&xharr",
- "description": "Bad named entity: xharr without a semi-colon",
- "output": [
- [
- "Character",
- "&xharr"
- ]
- ]
- },
- {
- "input": "⟷",
- "description": "Named entity: xharr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f7"
- ]
- ]
- },
- {
- "input": "&xi",
- "description": "Bad named entity: xi without a semi-colon",
- "output": [
- [
- "Character",
- "&xi"
- ]
- ]
- },
- {
- "input": "ξ",
- "description": "Named entity: xi; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03be"
- ]
- ]
- },
- {
- "input": "&xlArr",
- "description": "Bad named entity: xlArr without a semi-colon",
- "output": [
- [
- "Character",
- "&xlArr"
- ]
- ]
- },
- {
- "input": "⟸",
- "description": "Named entity: xlArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f8"
- ]
- ]
- },
- {
- "input": "&xlarr",
- "description": "Bad named entity: xlarr without a semi-colon",
- "output": [
- [
- "Character",
- "&xlarr"
- ]
- ]
- },
- {
- "input": "⟵",
- "description": "Named entity: xlarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f5"
- ]
- ]
- },
- {
- "input": "&xmap",
- "description": "Bad named entity: xmap without a semi-colon",
- "output": [
- [
- "Character",
- "&xmap"
- ]
- ]
- },
- {
- "input": "⟼",
- "description": "Named entity: xmap; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27fc"
- ]
- ]
- },
- {
- "input": "&xnis",
- "description": "Bad named entity: xnis without a semi-colon",
- "output": [
- [
- "Character",
- "&xnis"
- ]
- ]
- },
- {
- "input": "⋻",
- "description": "Named entity: xnis; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22fb"
- ]
- ]
- },
- {
- "input": "&xodot",
- "description": "Bad named entity: xodot without a semi-colon",
- "output": [
- [
- "Character",
- "&xodot"
- ]
- ]
- },
- {
- "input": "⨀",
- "description": "Named entity: xodot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a00"
- ]
- ]
- },
- {
- "input": "&xopf",
- "description": "Bad named entity: xopf without a semi-colon",
- "output": [
- [
- "Character",
- "&xopf"
- ]
- ]
- },
- {
- "input": "𝕩",
- "description": "Named entity: xopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd69"
- ]
- ]
- },
- {
- "input": "&xoplus",
- "description": "Bad named entity: xoplus without a semi-colon",
- "output": [
- [
- "Character",
- "&xoplus"
- ]
- ]
- },
- {
- "input": "⨁",
- "description": "Named entity: xoplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a01"
- ]
- ]
- },
- {
- "input": "&xotime",
- "description": "Bad named entity: xotime without a semi-colon",
- "output": [
- [
- "Character",
- "&xotime"
- ]
- ]
- },
- {
- "input": "⨂",
- "description": "Named entity: xotime; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a02"
- ]
- ]
- },
- {
- "input": "&xrArr",
- "description": "Bad named entity: xrArr without a semi-colon",
- "output": [
- [
- "Character",
- "&xrArr"
- ]
- ]
- },
- {
- "input": "⟹",
- "description": "Named entity: xrArr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f9"
- ]
- ]
- },
- {
- "input": "&xrarr",
- "description": "Bad named entity: xrarr without a semi-colon",
- "output": [
- [
- "Character",
- "&xrarr"
- ]
- ]
- },
- {
- "input": "⟶",
- "description": "Named entity: xrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u27f6"
- ]
- ]
- },
- {
- "input": "&xscr",
- "description": "Bad named entity: xscr without a semi-colon",
- "output": [
- [
- "Character",
- "&xscr"
- ]
- ]
- },
- {
- "input": "𝓍",
- "description": "Named entity: xscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udccd"
- ]
- ]
- },
- {
- "input": "&xsqcup",
- "description": "Bad named entity: xsqcup without a semi-colon",
- "output": [
- [
- "Character",
- "&xsqcup"
- ]
- ]
- },
- {
- "input": "⨆",
- "description": "Named entity: xsqcup; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a06"
- ]
- ]
- },
- {
- "input": "&xuplus",
- "description": "Bad named entity: xuplus without a semi-colon",
- "output": [
- [
- "Character",
- "&xuplus"
- ]
- ]
- },
- {
- "input": "⨄",
- "description": "Named entity: xuplus; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2a04"
- ]
- ]
- },
- {
- "input": "&xutri",
- "description": "Bad named entity: xutri without a semi-colon",
- "output": [
- [
- "Character",
- "&xutri"
- ]
- ]
- },
- {
- "input": "△",
- "description": "Named entity: xutri; with a semi-colon",
- "output": [
- [
- "Character",
- "\u25b3"
- ]
- ]
- },
- {
- "input": "&xvee",
- "description": "Bad named entity: xvee without a semi-colon",
- "output": [
- [
- "Character",
- "&xvee"
- ]
- ]
- },
- {
- "input": "⋁",
- "description": "Named entity: xvee; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c1"
- ]
- ]
- },
- {
- "input": "&xwedge",
- "description": "Bad named entity: xwedge without a semi-colon",
- "output": [
- [
- "Character",
- "&xwedge"
- ]
- ]
- },
- {
- "input": "⋀",
- "description": "Named entity: xwedge; with a semi-colon",
- "output": [
- [
- "Character",
- "\u22c0"
- ]
- ]
- },
- {
- "input": "ý",
- "description": "Named entity: yacute without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00fd"
- ]
- ]
- },
- {
- "input": "ý",
- "description": "Named entity: yacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00fd"
- ]
- ]
- },
- {
- "input": "&yacy",
- "description": "Bad named entity: yacy without a semi-colon",
- "output": [
- [
- "Character",
- "&yacy"
- ]
- ]
- },
- {
- "input": "я",
- "description": "Named entity: yacy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u044f"
- ]
- ]
- },
- {
- "input": "&ycirc",
- "description": "Bad named entity: ycirc without a semi-colon",
- "output": [
- [
- "Character",
- "&ycirc"
- ]
- ]
- },
- {
- "input": "ŷ",
- "description": "Named entity: ycirc; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0177"
- ]
- ]
- },
- {
- "input": "&ycy",
- "description": "Bad named entity: ycy without a semi-colon",
- "output": [
- [
- "Character",
- "&ycy"
- ]
- ]
- },
- {
- "input": "ы",
- "description": "Named entity: ycy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u044b"
- ]
- ]
- },
- {
- "input": "¥",
- "description": "Named entity: yen without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00a5"
- ]
- ]
- },
- {
- "input": "¥",
- "description": "Named entity: yen; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00a5"
- ]
- ]
- },
- {
- "input": "&yfr",
- "description": "Bad named entity: yfr without a semi-colon",
- "output": [
- [
- "Character",
- "&yfr"
- ]
- ]
- },
- {
- "input": "𝔶",
- "description": "Named entity: yfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd36"
- ]
- ]
- },
- {
- "input": "&yicy",
- "description": "Bad named entity: yicy without a semi-colon",
- "output": [
- [
- "Character",
- "&yicy"
- ]
- ]
- },
- {
- "input": "ї",
- "description": "Named entity: yicy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0457"
- ]
- ]
- },
- {
- "input": "&yopf",
- "description": "Bad named entity: yopf without a semi-colon",
- "output": [
- [
- "Character",
- "&yopf"
- ]
- ]
- },
- {
- "input": "𝕪",
- "description": "Named entity: yopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd6a"
- ]
- ]
- },
- {
- "input": "&yscr",
- "description": "Bad named entity: yscr without a semi-colon",
- "output": [
- [
- "Character",
- "&yscr"
- ]
- ]
- },
- {
- "input": "𝓎",
- "description": "Named entity: yscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udcce"
- ]
- ]
- },
- {
- "input": "&yucy",
- "description": "Bad named entity: yucy without a semi-colon",
- "output": [
- [
- "Character",
- "&yucy"
- ]
- ]
- },
- {
- "input": "ю",
- "description": "Named entity: yucy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u044e"
- ]
- ]
- },
- {
- "input": "ÿ",
- "description": "Named entity: yuml without a semi-colon",
- "output": [
- "ParseError",
- [
- "Character",
- "\u00ff"
- ]
- ]
- },
- {
- "input": "ÿ",
- "description": "Named entity: yuml; with a semi-colon",
- "output": [
- [
- "Character",
- "\u00ff"
- ]
- ]
- },
- {
- "input": "&zacute",
- "description": "Bad named entity: zacute without a semi-colon",
- "output": [
- [
- "Character",
- "&zacute"
- ]
- ]
- },
- {
- "input": "ź",
- "description": "Named entity: zacute; with a semi-colon",
- "output": [
- [
- "Character",
- "\u017a"
- ]
- ]
- },
- {
- "input": "&zcaron",
- "description": "Bad named entity: zcaron without a semi-colon",
- "output": [
- [
- "Character",
- "&zcaron"
- ]
- ]
- },
- {
- "input": "ž",
- "description": "Named entity: zcaron; with a semi-colon",
- "output": [
- [
- "Character",
- "\u017e"
- ]
- ]
- },
- {
- "input": "&zcy",
- "description": "Bad named entity: zcy without a semi-colon",
- "output": [
- [
- "Character",
- "&zcy"
- ]
- ]
- },
- {
- "input": "з",
- "description": "Named entity: zcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0437"
- ]
- ]
- },
- {
- "input": "&zdot",
- "description": "Bad named entity: zdot without a semi-colon",
- "output": [
- [
- "Character",
- "&zdot"
- ]
- ]
- },
- {
- "input": "ż",
- "description": "Named entity: zdot; with a semi-colon",
- "output": [
- [
- "Character",
- "\u017c"
- ]
- ]
- },
- {
- "input": "&zeetrf",
- "description": "Bad named entity: zeetrf without a semi-colon",
- "output": [
- [
- "Character",
- "&zeetrf"
- ]
- ]
- },
- {
- "input": "ℨ",
- "description": "Named entity: zeetrf; with a semi-colon",
- "output": [
- [
- "Character",
- "\u2128"
- ]
- ]
- },
- {
- "input": "&zeta",
- "description": "Bad named entity: zeta without a semi-colon",
- "output": [
- [
- "Character",
- "&zeta"
- ]
- ]
- },
- {
- "input": "ζ",
- "description": "Named entity: zeta; with a semi-colon",
- "output": [
- [
- "Character",
- "\u03b6"
- ]
- ]
- },
- {
- "input": "&zfr",
- "description": "Bad named entity: zfr without a semi-colon",
- "output": [
- [
- "Character",
- "&zfr"
- ]
- ]
- },
- {
- "input": "𝔷",
- "description": "Named entity: zfr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd37"
- ]
- ]
- },
- {
- "input": "&zhcy",
- "description": "Bad named entity: zhcy without a semi-colon",
- "output": [
- [
- "Character",
- "&zhcy"
- ]
- ]
- },
- {
- "input": "ж",
- "description": "Named entity: zhcy; with a semi-colon",
- "output": [
- [
- "Character",
- "\u0436"
- ]
- ]
- },
- {
- "input": "&zigrarr",
- "description": "Bad named entity: zigrarr without a semi-colon",
- "output": [
- [
- "Character",
- "&zigrarr"
- ]
- ]
- },
- {
- "input": "⇝",
- "description": "Named entity: zigrarr; with a semi-colon",
- "output": [
- [
- "Character",
- "\u21dd"
- ]
- ]
- },
- {
- "input": "&zopf",
- "description": "Bad named entity: zopf without a semi-colon",
- "output": [
- [
- "Character",
- "&zopf"
- ]
- ]
- },
- {
- "input": "𝕫",
- "description": "Named entity: zopf; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udd6b"
- ]
- ]
- },
- {
- "input": "&zscr",
- "description": "Bad named entity: zscr without a semi-colon",
- "output": [
- [
- "Character",
- "&zscr"
- ]
- ]
- },
- {
- "input": "𝓏",
- "description": "Named entity: zscr; with a semi-colon",
- "output": [
- [
- "Character",
- "\ud835\udccf"
- ]
- ]
- },
- {
- "input": "&zwj",
- "description": "Bad named entity: zwj without a semi-colon",
- "output": [
- [
- "Character",
- "&zwj"
- ]
- ]
- },
- {
- "input": "",
- "description": "Named entity: zwj; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200d"
- ]
- ]
- },
- {
- "input": "&zwnj",
- "description": "Bad named entity: zwnj without a semi-colon",
- "output": [
- [
- "Character",
- "&zwnj"
- ]
- ]
- },
- {
- "input": "",
- "description": "Named entity: zwnj; with a semi-colon",
- "output": [
- [
- "Character",
- "\u200c"
- ]
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/libs/html5lib/tests/testdata/tokenizer/numericEntities.test b/libs/html5lib/tests/testdata/tokenizer/numericEntities.test
deleted file mode 100644
index 43de84b0f..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/numericEntities.test
+++ /dev/null
@@ -1,1349 +0,0 @@
-{"tests": [
-
-{"description": "Invalid unterminated numeric entity character overflow before EOF",
-"input": "",
-"output": ["ParseError", "ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid unterminated numeric entity character overflow before EOF",
-"input": "",
-"output": ["ParseError", "ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid unterminated numeric entity character overflow before EOF",
-"input": "",
-"output": ["ParseError", "ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid unterminated numeric entity character overflow",
-"input": "x",
-"output": ["ParseError", "ParseError", ["Character", "\uFFFDx"]]},
-
-{"description": "Invalid unterminated numeric entity character overflow",
-"input": "x",
-"output": ["ParseError", "ParseError", ["Character", "\uFFFDx"]]},
-
-{"description": "Invalid unterminated numeric entity character overflow",
-"input": "x",
-"output": ["ParseError", "ParseError", ["Character", "\uFFFDx"]]},
-
-{"description": "Invalid numeric entity character overflow",
-"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid numeric entity character overflow",
-"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid numeric entity character overflow",
-"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid numeric entity character U+0000",
-"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid numeric entity character U+0001",
-"input": "",
-"output": ["ParseError", ["Character", "\u0001"]]},
-
-{"description": "Invalid numeric entity character U+0002",
-"input": "",
-"output": ["ParseError", ["Character", "\u0002"]]},
-
-{"description": "Invalid numeric entity character U+0003",
-"input": "",
-"output": ["ParseError", ["Character", "\u0003"]]},
-
-{"description": "Invalid numeric entity character U+0004",
-"input": "",
-"output": ["ParseError", ["Character", "\u0004"]]},
-
-{"description": "Invalid numeric entity character U+0005",
-"input": "",
-"output": ["ParseError", ["Character", "\u0005"]]},
-
-{"description": "Invalid numeric entity character U+0006",
-"input": "",
-"output": ["ParseError", ["Character", "\u0006"]]},
-
-{"description": "Invalid numeric entity character U+0007",
-"input": "",
-"output": ["ParseError", ["Character", "\u0007"]]},
-
-{"description": "Invalid numeric entity character U+0008",
-"input": "",
-"output": ["ParseError", ["Character", "\u0008"]]},
-
-{"description": "Invalid numeric entity character U+000B",
-"input": "",
-"output": ["ParseError", ["Character", "\u000b"]]},
-
-{"description": "Invalid numeric entity character U+000E",
-"input": "",
-"output": ["ParseError", ["Character", "\u000e"]]},
-
-{"description": "Invalid numeric entity character U+000F",
-"input": "",
-"output": ["ParseError", ["Character", "\u000f"]]},
-
-{"description": "Invalid numeric entity character U+0010",
-"input": "",
-"output": ["ParseError", ["Character", "\u0010"]]},
-
-{"description": "Invalid numeric entity character U+0011",
-"input": "",
-"output": ["ParseError", ["Character", "\u0011"]]},
-
-{"description": "Invalid numeric entity character U+0012",
-"input": "",
-"output": ["ParseError", ["Character", "\u0012"]]},
-
-{"description": "Invalid numeric entity character U+0013",
-"input": "",
-"output": ["ParseError", ["Character", "\u0013"]]},
-
-{"description": "Invalid numeric entity character U+0014",
-"input": "",
-"output": ["ParseError", ["Character", "\u0014"]]},
-
-{"description": "Invalid numeric entity character U+0015",
-"input": "",
-"output": ["ParseError", ["Character", "\u0015"]]},
-
-{"description": "Invalid numeric entity character U+0016",
-"input": "",
-"output": ["ParseError", ["Character", "\u0016"]]},
-
-{"description": "Invalid numeric entity character U+0017",
-"input": "",
-"output": ["ParseError", ["Character", "\u0017"]]},
-
-{"description": "Invalid numeric entity character U+0018",
-"input": "",
-"output": ["ParseError", ["Character", "\u0018"]]},
-
-{"description": "Invalid numeric entity character U+0019",
-"input": "",
-"output": ["ParseError", ["Character", "\u0019"]]},
-
-{"description": "Invalid numeric entity character U+001A",
-"input": "",
-"output": ["ParseError", ["Character", "\u001a"]]},
-
-{"description": "Invalid numeric entity character U+001B",
-"input": "",
-"output": ["ParseError", ["Character", "\u001b"]]},
-
-{"description": "Invalid numeric entity character U+001C",
-"input": "",
-"output": ["ParseError", ["Character", "\u001c"]]},
-
-{"description": "Invalid numeric entity character U+001D",
-"input": "",
-"output": ["ParseError", ["Character", "\u001d"]]},
-
-{"description": "Invalid numeric entity character U+001E",
-"input": "",
-"output": ["ParseError", ["Character", "\u001e"]]},
-
-{"description": "Invalid numeric entity character U+001F",
-"input": "",
-"output": ["ParseError", ["Character", "\u001f"]]},
-
-{"description": "Invalid numeric entity character U+007F",
-"input": "",
-"output": ["ParseError", ["Character", "\u007f"]]},
-
-{"description": "Invalid numeric entity character U+D800",
-"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid numeric entity character U+DFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
-
-{"description": "Invalid numeric entity character U+FDD0",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd0"]]},
-
-{"description": "Invalid numeric entity character U+FDD1",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd1"]]},
-
-{"description": "Invalid numeric entity character U+FDD2",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd2"]]},
-
-{"description": "Invalid numeric entity character U+FDD3",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd3"]]},
-
-{"description": "Invalid numeric entity character U+FDD4",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd4"]]},
-
-{"description": "Invalid numeric entity character U+FDD5",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd5"]]},
-
-{"description": "Invalid numeric entity character U+FDD6",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd6"]]},
-
-{"description": "Invalid numeric entity character U+FDD7",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd7"]]},
-
-{"description": "Invalid numeric entity character U+FDD8",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd8"]]},
-
-{"description": "Invalid numeric entity character U+FDD9",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdd9"]]},
-
-{"description": "Invalid numeric entity character U+FDDA",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdda"]]},
-
-{"description": "Invalid numeric entity character U+FDDB",
-"input": "",
-"output": ["ParseError", ["Character", "\ufddb"]]},
-
-{"description": "Invalid numeric entity character U+FDDC",
-"input": "",
-"output": ["ParseError", ["Character", "\ufddc"]]},
-
-{"description": "Invalid numeric entity character U+FDDD",
-"input": "",
-"output": ["ParseError", ["Character", "\ufddd"]]},
-
-{"description": "Invalid numeric entity character U+FDDE",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdde"]]},
-
-{"description": "Invalid numeric entity character U+FDDF",
-"input": "",
-"output": ["ParseError", ["Character", "\ufddf"]]},
-
-{"description": "Invalid numeric entity character U+FDE0",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde0"]]},
-
-{"description": "Invalid numeric entity character U+FDE1",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde1"]]},
-
-{"description": "Invalid numeric entity character U+FDE2",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde2"]]},
-
-{"description": "Invalid numeric entity character U+FDE3",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde3"]]},
-
-{"description": "Invalid numeric entity character U+FDE4",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde4"]]},
-
-{"description": "Invalid numeric entity character U+FDE5",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde5"]]},
-
-{"description": "Invalid numeric entity character U+FDE6",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde6"]]},
-
-{"description": "Invalid numeric entity character U+FDE7",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde7"]]},
-
-{"description": "Invalid numeric entity character U+FDE8",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde8"]]},
-
-{"description": "Invalid numeric entity character U+FDE9",
-"input": "",
-"output": ["ParseError", ["Character", "\ufde9"]]},
-
-{"description": "Invalid numeric entity character U+FDEA",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdea"]]},
-
-{"description": "Invalid numeric entity character U+FDEB",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdeb"]]},
-
-{"description": "Invalid numeric entity character U+FDEC",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdec"]]},
-
-{"description": "Invalid numeric entity character U+FDED",
-"input": "",
-"output": ["ParseError", ["Character", "\ufded"]]},
-
-{"description": "Invalid numeric entity character U+FDEE",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdee"]]},
-
-{"description": "Invalid numeric entity character U+FDEF",
-"input": "",
-"output": ["ParseError", ["Character", "\ufdef"]]},
-
-{"description": "Invalid numeric entity character U+FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\ufffe"]]},
-
-{"description": "Invalid numeric entity character U+FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uffff"]]},
-
-{"description": "Invalid numeric entity character U+1FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uD83F\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+1FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uD83F\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+2FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uD87F\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+2FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uD87F\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+3FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uD8BF\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+3FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uD8BF\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+4FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uD8FF\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+4FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uD8FF\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+5FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uD93F\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+5FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uD93F\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+6FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uD97F\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+6FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uD97F\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+7FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uD9BF\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+7FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uD9BF\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+8FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uD9FF\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+8FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uD9FF\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+9FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uDA3F\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+9FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uDA3F\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+AFFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uDA7F\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+AFFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uDA7F\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+BFFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uDABF\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+BFFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uDABF\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+CFFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uDAFF\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+CFFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uDAFF\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+DFFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uDB3F\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+DFFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uDB3F\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+EFFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uDB7F\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+EFFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uDB7F\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+FFFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uDBBF\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+FFFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uDBBF\uDFFF"]]},
-
-{"description": "Invalid numeric entity character U+10FFFE",
-"input": "",
-"output": ["ParseError", ["Character", "\uDBFF\uDFFE"]]},
-
-{"description": "Invalid numeric entity character U+10FFFF",
-"input": "",
-"output": ["ParseError", ["Character", "\uDBFF\uDFFF"]]},
-
-{"description": "Valid numeric entity character U+0009",
-"input": " ",
-"output": [["Character", "\u0009"]]},
-
-{"description": "Valid numeric entity character U+000A",
-"input": "
",
-"output": [["Character", "\u000A"]]},
-
-{"description": "Valid numeric entity character U+0020",
-"input": " ",
-"output": [["Character", "\u0020"]]},
-
-{"description": "Valid numeric entity character U+0021",
-"input": "!",
-"output": [["Character", "\u0021"]]},
-
-{"description": "Valid numeric entity character U+0022",
-"input": """,
-"output": [["Character", "\u0022"]]},
-
-{"description": "Valid numeric entity character U+0023",
-"input": "#",
-"output": [["Character", "\u0023"]]},
-
-{"description": "Valid numeric entity character U+0024",
-"input": "$",
-"output": [["Character", "\u0024"]]},
-
-{"description": "Valid numeric entity character U+0025",
-"input": "%",
-"output": [["Character", "\u0025"]]},
-
-{"description": "Valid numeric entity character U+0026",
-"input": "&",
-"output": [["Character", "\u0026"]]},
-
-{"description": "Valid numeric entity character U+0027",
-"input": "'",
-"output": [["Character", "\u0027"]]},
-
-{"description": "Valid numeric entity character U+0028",
-"input": "(",
-"output": [["Character", "\u0028"]]},
-
-{"description": "Valid numeric entity character U+0029",
-"input": ")",
-"output": [["Character", "\u0029"]]},
-
-{"description": "Valid numeric entity character U+002A",
-"input": "*",
-"output": [["Character", "\u002A"]]},
-
-{"description": "Valid numeric entity character U+002B",
-"input": "+",
-"output": [["Character", "\u002B"]]},
-
-{"description": "Valid numeric entity character U+002C",
-"input": ",",
-"output": [["Character", "\u002C"]]},
-
-{"description": "Valid numeric entity character U+002D",
-"input": "-",
-"output": [["Character", "\u002D"]]},
-
-{"description": "Valid numeric entity character U+002E",
-"input": ".",
-"output": [["Character", "\u002E"]]},
-
-{"description": "Valid numeric entity character U+002F",
-"input": "/",
-"output": [["Character", "\u002F"]]},
-
-{"description": "Valid numeric entity character U+0030",
-"input": "0",
-"output": [["Character", "\u0030"]]},
-
-{"description": "Valid numeric entity character U+0031",
-"input": "1",
-"output": [["Character", "\u0031"]]},
-
-{"description": "Valid numeric entity character U+0032",
-"input": "2",
-"output": [["Character", "\u0032"]]},
-
-{"description": "Valid numeric entity character U+0033",
-"input": "3",
-"output": [["Character", "\u0033"]]},
-
-{"description": "Valid numeric entity character U+0034",
-"input": "4",
-"output": [["Character", "\u0034"]]},
-
-{"description": "Valid numeric entity character U+0035",
-"input": "5",
-"output": [["Character", "\u0035"]]},
-
-{"description": "Valid numeric entity character U+0036",
-"input": "6",
-"output": [["Character", "\u0036"]]},
-
-{"description": "Valid numeric entity character U+0037",
-"input": "7",
-"output": [["Character", "\u0037"]]},
-
-{"description": "Valid numeric entity character U+0038",
-"input": "8",
-"output": [["Character", "\u0038"]]},
-
-{"description": "Valid numeric entity character U+0039",
-"input": "9",
-"output": [["Character", "\u0039"]]},
-
-{"description": "Valid numeric entity character U+003A",
-"input": ":",
-"output": [["Character", "\u003A"]]},
-
-{"description": "Valid numeric entity character U+003B",
-"input": ";",
-"output": [["Character", "\u003B"]]},
-
-{"description": "Valid numeric entity character U+003C",
-"input": "<",
-"output": [["Character", "\u003C"]]},
-
-{"description": "Valid numeric entity character U+003D",
-"input": "=",
-"output": [["Character", "\u003D"]]},
-
-{"description": "Valid numeric entity character U+003E",
-"input": ">",
-"output": [["Character", "\u003E"]]},
-
-{"description": "Valid numeric entity character U+003F",
-"input": "?",
-"output": [["Character", "\u003F"]]},
-
-{"description": "Valid numeric entity character U+0040",
-"input": "@",
-"output": [["Character", "\u0040"]]},
-
-{"description": "Valid numeric entity character U+0041",
-"input": "A",
-"output": [["Character", "\u0041"]]},
-
-{"description": "Valid numeric entity character U+0042",
-"input": "B",
-"output": [["Character", "\u0042"]]},
-
-{"description": "Valid numeric entity character U+0043",
-"input": "C",
-"output": [["Character", "\u0043"]]},
-
-{"description": "Valid numeric entity character U+0044",
-"input": "D",
-"output": [["Character", "\u0044"]]},
-
-{"description": "Valid numeric entity character U+0045",
-"input": "E",
-"output": [["Character", "\u0045"]]},
-
-{"description": "Valid numeric entity character U+0046",
-"input": "F",
-"output": [["Character", "\u0046"]]},
-
-{"description": "Valid numeric entity character U+0047",
-"input": "G",
-"output": [["Character", "\u0047"]]},
-
-{"description": "Valid numeric entity character U+0048",
-"input": "H",
-"output": [["Character", "\u0048"]]},
-
-{"description": "Valid numeric entity character U+0049",
-"input": "I",
-"output": [["Character", "\u0049"]]},
-
-{"description": "Valid numeric entity character U+004A",
-"input": "J",
-"output": [["Character", "\u004A"]]},
-
-{"description": "Valid numeric entity character U+004B",
-"input": "K",
-"output": [["Character", "\u004B"]]},
-
-{"description": "Valid numeric entity character U+004C",
-"input": "L",
-"output": [["Character", "\u004C"]]},
-
-{"description": "Valid numeric entity character U+004D",
-"input": "M",
-"output": [["Character", "\u004D"]]},
-
-{"description": "Valid numeric entity character U+004E",
-"input": "N",
-"output": [["Character", "\u004E"]]},
-
-{"description": "Valid numeric entity character U+004F",
-"input": "O",
-"output": [["Character", "\u004F"]]},
-
-{"description": "Valid numeric entity character U+0050",
-"input": "P",
-"output": [["Character", "\u0050"]]},
-
-{"description": "Valid numeric entity character U+0051",
-"input": "Q",
-"output": [["Character", "\u0051"]]},
-
-{"description": "Valid numeric entity character U+0052",
-"input": "R",
-"output": [["Character", "\u0052"]]},
-
-{"description": "Valid numeric entity character U+0053",
-"input": "S",
-"output": [["Character", "\u0053"]]},
-
-{"description": "Valid numeric entity character U+0054",
-"input": "T",
-"output": [["Character", "\u0054"]]},
-
-{"description": "Valid numeric entity character U+0055",
-"input": "U",
-"output": [["Character", "\u0055"]]},
-
-{"description": "Valid numeric entity character U+0056",
-"input": "V",
-"output": [["Character", "\u0056"]]},
-
-{"description": "Valid numeric entity character U+0057",
-"input": "W",
-"output": [["Character", "\u0057"]]},
-
-{"description": "Valid numeric entity character U+0058",
-"input": "X",
-"output": [["Character", "\u0058"]]},
-
-{"description": "Valid numeric entity character U+0059",
-"input": "Y",
-"output": [["Character", "\u0059"]]},
-
-{"description": "Valid numeric entity character U+005A",
-"input": "Z",
-"output": [["Character", "\u005A"]]},
-
-{"description": "Valid numeric entity character U+005B",
-"input": "[",
-"output": [["Character", "\u005B"]]},
-
-{"description": "Valid numeric entity character U+005C",
-"input": "\",
-"output": [["Character", "\u005C"]]},
-
-{"description": "Valid numeric entity character U+005D",
-"input": "]",
-"output": [["Character", "\u005D"]]},
-
-{"description": "Valid numeric entity character U+005E",
-"input": "^",
-"output": [["Character", "\u005E"]]},
-
-{"description": "Valid numeric entity character U+005F",
-"input": "_",
-"output": [["Character", "\u005F"]]},
-
-{"description": "Valid numeric entity character U+0060",
-"input": "`",
-"output": [["Character", "\u0060"]]},
-
-{"description": "Valid numeric entity character U+0061",
-"input": "a",
-"output": [["Character", "\u0061"]]},
-
-{"description": "Valid numeric entity character U+0062",
-"input": "b",
-"output": [["Character", "\u0062"]]},
-
-{"description": "Valid numeric entity character U+0063",
-"input": "c",
-"output": [["Character", "\u0063"]]},
-
-{"description": "Valid numeric entity character U+0064",
-"input": "d",
-"output": [["Character", "\u0064"]]},
-
-{"description": "Valid numeric entity character U+0065",
-"input": "e",
-"output": [["Character", "\u0065"]]},
-
-{"description": "Valid numeric entity character U+0066",
-"input": "f",
-"output": [["Character", "\u0066"]]},
-
-{"description": "Valid numeric entity character U+0067",
-"input": "g",
-"output": [["Character", "\u0067"]]},
-
-{"description": "Valid numeric entity character U+0068",
-"input": "h",
-"output": [["Character", "\u0068"]]},
-
-{"description": "Valid numeric entity character U+0069",
-"input": "i",
-"output": [["Character", "\u0069"]]},
-
-{"description": "Valid numeric entity character U+006A",
-"input": "j",
-"output": [["Character", "\u006A"]]},
-
-{"description": "Valid numeric entity character U+006B",
-"input": "k",
-"output": [["Character", "\u006B"]]},
-
-{"description": "Valid numeric entity character U+006C",
-"input": "l",
-"output": [["Character", "\u006C"]]},
-
-{"description": "Valid numeric entity character U+006D",
-"input": "m",
-"output": [["Character", "\u006D"]]},
-
-{"description": "Valid numeric entity character U+006E",
-"input": "n",
-"output": [["Character", "\u006E"]]},
-
-{"description": "Valid numeric entity character U+006F",
-"input": "o",
-"output": [["Character", "\u006F"]]},
-
-{"description": "Valid numeric entity character U+0070",
-"input": "p",
-"output": [["Character", "\u0070"]]},
-
-{"description": "Valid numeric entity character U+0071",
-"input": "q",
-"output": [["Character", "\u0071"]]},
-
-{"description": "Valid numeric entity character U+0072",
-"input": "r",
-"output": [["Character", "\u0072"]]},
-
-{"description": "Valid numeric entity character U+0073",
-"input": "s",
-"output": [["Character", "\u0073"]]},
-
-{"description": "Valid numeric entity character U+0074",
-"input": "t",
-"output": [["Character", "\u0074"]]},
-
-{"description": "Valid numeric entity character U+0075",
-"input": "u",
-"output": [["Character", "\u0075"]]},
-
-{"description": "Valid numeric entity character U+0076",
-"input": "v",
-"output": [["Character", "\u0076"]]},
-
-{"description": "Valid numeric entity character U+0077",
-"input": "w",
-"output": [["Character", "\u0077"]]},
-
-{"description": "Valid numeric entity character U+0078",
-"input": "x",
-"output": [["Character", "\u0078"]]},
-
-{"description": "Valid numeric entity character U+0079",
-"input": "y",
-"output": [["Character", "\u0079"]]},
-
-{"description": "Valid numeric entity character U+007A",
-"input": "z",
-"output": [["Character", "\u007A"]]},
-
-{"description": "Valid numeric entity character U+007B",
-"input": "{",
-"output": [["Character", "\u007B"]]},
-
-{"description": "Valid numeric entity character U+007C",
-"input": "|",
-"output": [["Character", "\u007C"]]},
-
-{"description": "Valid numeric entity character U+007D",
-"input": "}",
-"output": [["Character", "\u007D"]]},
-
-{"description": "Valid numeric entity character U+007E",
-"input": "~",
-"output": [["Character", "\u007E"]]},
-
-{"description": "Valid numeric entity character U+00A0",
-"input": " ",
-"output": [["Character", "\u00A0"]]},
-
-{"description": "Valid numeric entity character U+00A1",
-"input": "¡",
-"output": [["Character", "\u00A1"]]},
-
-{"description": "Valid numeric entity character U+00A2",
-"input": "¢",
-"output": [["Character", "\u00A2"]]},
-
-{"description": "Valid numeric entity character U+00A3",
-"input": "£",
-"output": [["Character", "\u00A3"]]},
-
-{"description": "Valid numeric entity character U+00A4",
-"input": "¤",
-"output": [["Character", "\u00A4"]]},
-
-{"description": "Valid numeric entity character U+00A5",
-"input": "¥",
-"output": [["Character", "\u00A5"]]},
-
-{"description": "Valid numeric entity character U+00A6",
-"input": "¦",
-"output": [["Character", "\u00A6"]]},
-
-{"description": "Valid numeric entity character U+00A7",
-"input": "§",
-"output": [["Character", "\u00A7"]]},
-
-{"description": "Valid numeric entity character U+00A8",
-"input": "¨",
-"output": [["Character", "\u00A8"]]},
-
-{"description": "Valid numeric entity character U+00A9",
-"input": "©",
-"output": [["Character", "\u00A9"]]},
-
-{"description": "Valid numeric entity character U+00AA",
-"input": "ª",
-"output": [["Character", "\u00AA"]]},
-
-{"description": "Valid numeric entity character U+00AB",
-"input": "«",
-"output": [["Character", "\u00AB"]]},
-
-{"description": "Valid numeric entity character U+00AC",
-"input": "¬",
-"output": [["Character", "\u00AC"]]},
-
-{"description": "Valid numeric entity character U+00AD",
-"input": "",
-"output": [["Character", "\u00AD"]]},
-
-{"description": "Valid numeric entity character U+00AE",
-"input": "®",
-"output": [["Character", "\u00AE"]]},
-
-{"description": "Valid numeric entity character U+00AF",
-"input": "¯",
-"output": [["Character", "\u00AF"]]},
-
-{"description": "Valid numeric entity character U+00B0",
-"input": "°",
-"output": [["Character", "\u00B0"]]},
-
-{"description": "Valid numeric entity character U+00B1",
-"input": "±",
-"output": [["Character", "\u00B1"]]},
-
-{"description": "Valid numeric entity character U+00B2",
-"input": "²",
-"output": [["Character", "\u00B2"]]},
-
-{"description": "Valid numeric entity character U+00B3",
-"input": "³",
-"output": [["Character", "\u00B3"]]},
-
-{"description": "Valid numeric entity character U+00B4",
-"input": "´",
-"output": [["Character", "\u00B4"]]},
-
-{"description": "Valid numeric entity character U+00B5",
-"input": "µ",
-"output": [["Character", "\u00B5"]]},
-
-{"description": "Valid numeric entity character U+00B6",
-"input": "¶",
-"output": [["Character", "\u00B6"]]},
-
-{"description": "Valid numeric entity character U+00B7",
-"input": "·",
-"output": [["Character", "\u00B7"]]},
-
-{"description": "Valid numeric entity character U+00B8",
-"input": "¸",
-"output": [["Character", "\u00B8"]]},
-
-{"description": "Valid numeric entity character U+00B9",
-"input": "¹",
-"output": [["Character", "\u00B9"]]},
-
-{"description": "Valid numeric entity character U+00BA",
-"input": "º",
-"output": [["Character", "\u00BA"]]},
-
-{"description": "Valid numeric entity character U+00BB",
-"input": "»",
-"output": [["Character", "\u00BB"]]},
-
-{"description": "Valid numeric entity character U+00BC",
-"input": "¼",
-"output": [["Character", "\u00BC"]]},
-
-{"description": "Valid numeric entity character U+00BD",
-"input": "½",
-"output": [["Character", "\u00BD"]]},
-
-{"description": "Valid numeric entity character U+00BE",
-"input": "¾",
-"output": [["Character", "\u00BE"]]},
-
-{"description": "Valid numeric entity character U+00BF",
-"input": "¿",
-"output": [["Character", "\u00BF"]]},
-
-{"description": "Valid numeric entity character U+00C0",
-"input": "À",
-"output": [["Character", "\u00C0"]]},
-
-{"description": "Valid numeric entity character U+00C1",
-"input": "Á",
-"output": [["Character", "\u00C1"]]},
-
-{"description": "Valid numeric entity character U+00C2",
-"input": "Â",
-"output": [["Character", "\u00C2"]]},
-
-{"description": "Valid numeric entity character U+00C3",
-"input": "Ã",
-"output": [["Character", "\u00C3"]]},
-
-{"description": "Valid numeric entity character U+00C4",
-"input": "Ä",
-"output": [["Character", "\u00C4"]]},
-
-{"description": "Valid numeric entity character U+00C5",
-"input": "Å",
-"output": [["Character", "\u00C5"]]},
-
-{"description": "Valid numeric entity character U+00C6",
-"input": "Æ",
-"output": [["Character", "\u00C6"]]},
-
-{"description": "Valid numeric entity character U+00C7",
-"input": "Ç",
-"output": [["Character", "\u00C7"]]},
-
-{"description": "Valid numeric entity character U+00C8",
-"input": "È",
-"output": [["Character", "\u00C8"]]},
-
-{"description": "Valid numeric entity character U+00C9",
-"input": "É",
-"output": [["Character", "\u00C9"]]},
-
-{"description": "Valid numeric entity character U+00CA",
-"input": "Ê",
-"output": [["Character", "\u00CA"]]},
-
-{"description": "Valid numeric entity character U+00CB",
-"input": "Ë",
-"output": [["Character", "\u00CB"]]},
-
-{"description": "Valid numeric entity character U+00CC",
-"input": "Ì",
-"output": [["Character", "\u00CC"]]},
-
-{"description": "Valid numeric entity character U+00CD",
-"input": "Í",
-"output": [["Character", "\u00CD"]]},
-
-{"description": "Valid numeric entity character U+00CE",
-"input": "Î",
-"output": [["Character", "\u00CE"]]},
-
-{"description": "Valid numeric entity character U+00CF",
-"input": "Ï",
-"output": [["Character", "\u00CF"]]},
-
-{"description": "Valid numeric entity character U+00D0",
-"input": "Ð",
-"output": [["Character", "\u00D0"]]},
-
-{"description": "Valid numeric entity character U+00D1",
-"input": "Ñ",
-"output": [["Character", "\u00D1"]]},
-
-{"description": "Valid numeric entity character U+00D2",
-"input": "Ò",
-"output": [["Character", "\u00D2"]]},
-
-{"description": "Valid numeric entity character U+00D3",
-"input": "Ó",
-"output": [["Character", "\u00D3"]]},
-
-{"description": "Valid numeric entity character U+00D4",
-"input": "Ô",
-"output": [["Character", "\u00D4"]]},
-
-{"description": "Valid numeric entity character U+00D5",
-"input": "Õ",
-"output": [["Character", "\u00D5"]]},
-
-{"description": "Valid numeric entity character U+00D6",
-"input": "Ö",
-"output": [["Character", "\u00D6"]]},
-
-{"description": "Valid numeric entity character U+00D7",
-"input": "×",
-"output": [["Character", "\u00D7"]]},
-
-{"description": "Valid numeric entity character U+00D8",
-"input": "Ø",
-"output": [["Character", "\u00D8"]]},
-
-{"description": "Valid numeric entity character U+00D9",
-"input": "Ù",
-"output": [["Character", "\u00D9"]]},
-
-{"description": "Valid numeric entity character U+00DA",
-"input": "Ú",
-"output": [["Character", "\u00DA"]]},
-
-{"description": "Valid numeric entity character U+00DB",
-"input": "Û",
-"output": [["Character", "\u00DB"]]},
-
-{"description": "Valid numeric entity character U+00DC",
-"input": "Ü",
-"output": [["Character", "\u00DC"]]},
-
-{"description": "Valid numeric entity character U+00DD",
-"input": "Ý",
-"output": [["Character", "\u00DD"]]},
-
-{"description": "Valid numeric entity character U+00DE",
-"input": "Þ",
-"output": [["Character", "\u00DE"]]},
-
-{"description": "Valid numeric entity character U+00DF",
-"input": "ß",
-"output": [["Character", "\u00DF"]]},
-
-{"description": "Valid numeric entity character U+00E0",
-"input": "à",
-"output": [["Character", "\u00E0"]]},
-
-{"description": "Valid numeric entity character U+00E1",
-"input": "á",
-"output": [["Character", "\u00E1"]]},
-
-{"description": "Valid numeric entity character U+00E2",
-"input": "â",
-"output": [["Character", "\u00E2"]]},
-
-{"description": "Valid numeric entity character U+00E3",
-"input": "ã",
-"output": [["Character", "\u00E3"]]},
-
-{"description": "Valid numeric entity character U+00E4",
-"input": "ä",
-"output": [["Character", "\u00E4"]]},
-
-{"description": "Valid numeric entity character U+00E5",
-"input": "å",
-"output": [["Character", "\u00E5"]]},
-
-{"description": "Valid numeric entity character U+00E6",
-"input": "æ",
-"output": [["Character", "\u00E6"]]},
-
-{"description": "Valid numeric entity character U+00E7",
-"input": "ç",
-"output": [["Character", "\u00E7"]]},
-
-{"description": "Valid numeric entity character U+00E8",
-"input": "è",
-"output": [["Character", "\u00E8"]]},
-
-{"description": "Valid numeric entity character U+00E9",
-"input": "é",
-"output": [["Character", "\u00E9"]]},
-
-{"description": "Valid numeric entity character U+00EA",
-"input": "ê",
-"output": [["Character", "\u00EA"]]},
-
-{"description": "Valid numeric entity character U+00EB",
-"input": "ë",
-"output": [["Character", "\u00EB"]]},
-
-{"description": "Valid numeric entity character U+00EC",
-"input": "ì",
-"output": [["Character", "\u00EC"]]},
-
-{"description": "Valid numeric entity character U+00ED",
-"input": "í",
-"output": [["Character", "\u00ED"]]},
-
-{"description": "Valid numeric entity character U+00EE",
-"input": "î",
-"output": [["Character", "\u00EE"]]},
-
-{"description": "Valid numeric entity character U+00EF",
-"input": "ï",
-"output": [["Character", "\u00EF"]]},
-
-{"description": "Valid numeric entity character U+00F0",
-"input": "ð",
-"output": [["Character", "\u00F0"]]},
-
-{"description": "Valid numeric entity character U+00F1",
-"input": "ñ",
-"output": [["Character", "\u00F1"]]},
-
-{"description": "Valid numeric entity character U+00F2",
-"input": "ò",
-"output": [["Character", "\u00F2"]]},
-
-{"description": "Valid numeric entity character U+00F3",
-"input": "ó",
-"output": [["Character", "\u00F3"]]},
-
-{"description": "Valid numeric entity character U+00F4",
-"input": "ô",
-"output": [["Character", "\u00F4"]]},
-
-{"description": "Valid numeric entity character U+00F5",
-"input": "õ",
-"output": [["Character", "\u00F5"]]},
-
-{"description": "Valid numeric entity character U+00F6",
-"input": "ö",
-"output": [["Character", "\u00F6"]]},
-
-{"description": "Valid numeric entity character U+00F7",
-"input": "÷",
-"output": [["Character", "\u00F7"]]},
-
-{"description": "Valid numeric entity character U+00F8",
-"input": "ø",
-"output": [["Character", "\u00F8"]]},
-
-{"description": "Valid numeric entity character U+00F9",
-"input": "ù",
-"output": [["Character", "\u00F9"]]},
-
-{"description": "Valid numeric entity character U+00FA",
-"input": "ú",
-"output": [["Character", "\u00FA"]]},
-
-{"description": "Valid numeric entity character U+00FB",
-"input": "û",
-"output": [["Character", "\u00FB"]]},
-
-{"description": "Valid numeric entity character U+00FC",
-"input": "ü",
-"output": [["Character", "\u00FC"]]},
-
-{"description": "Valid numeric entity character U+00FD",
-"input": "ý",
-"output": [["Character", "\u00FD"]]},
-
-{"description": "Valid numeric entity character U+00FE",
-"input": "þ",
-"output": [["Character", "\u00FE"]]},
-
-{"description": "Valid numeric entity character U+00FF",
-"input": "ÿ",
-"output": [["Character", "\u00FF"]]},
-
-{"description": "Valid numeric entity character U+D7FF",
-"input": "",
-"output": [["Character", "\uD7FF"]]},
-
-{"description": "Valid numeric entity character U+E000",
-"input": "",
-"output": [["Character", "\uE000"]]},
-
-{"description": "Valid numeric entity character U+FDCF",
-"input": "﷏",
-"output": [["Character", "\uFDCF"]]},
-
-{"description": "Valid numeric entity character U+FDF0",
-"input": "ﷰ",
-"output": [["Character", "\uFDF0"]]},
-
-{"description": "Valid numeric entity character U+FFFD",
-"input": "�",
-"output": [["Character", "\uFFFD"]]},
-
-{"description": "Valid numeric entity character U+10000",
-"input": "𐀀",
-"output": [["Character", "\uD800\uDC00"]]},
-
-{"description": "Valid numeric entity character U+1FFFD",
-"input": "",
-"output": [["Character", "\uD83F\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+20000",
-"input": "𠀀",
-"output": [["Character", "\uD840\uDC00"]]},
-
-{"description": "Valid numeric entity character U+2FFFD",
-"input": "",
-"output": [["Character", "\uD87F\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+30000",
-"input": "𰀀",
-"output": [["Character", "\uD880\uDC00"]]},
-
-{"description": "Valid numeric entity character U+3FFFD",
-"input": "",
-"output": [["Character", "\uD8BF\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+40000",
-"input": "",
-"output": [["Character", "\uD8C0\uDC00"]]},
-
-{"description": "Valid numeric entity character U+4FFFD",
-"input": "",
-"output": [["Character", "\uD8FF\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+50000",
-"input": "",
-"output": [["Character", "\uD900\uDC00"]]},
-
-{"description": "Valid numeric entity character U+5FFFD",
-"input": "",
-"output": [["Character", "\uD93F\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+60000",
-"input": "",
-"output": [["Character", "\uD940\uDC00"]]},
-
-{"description": "Valid numeric entity character U+6FFFD",
-"input": "",
-"output": [["Character", "\uD97F\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+70000",
-"input": "",
-"output": [["Character", "\uD980\uDC00"]]},
-
-{"description": "Valid numeric entity character U+7FFFD",
-"input": "",
-"output": [["Character", "\uD9BF\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+80000",
-"input": "",
-"output": [["Character", "\uD9C0\uDC00"]]},
-
-{"description": "Valid numeric entity character U+8FFFD",
-"input": "",
-"output": [["Character", "\uD9FF\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+90000",
-"input": "",
-"output": [["Character", "\uDA00\uDC00"]]},
-
-{"description": "Valid numeric entity character U+9FFFD",
-"input": "",
-"output": [["Character", "\uDA3F\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+A0000",
-"input": "",
-"output": [["Character", "\uDA40\uDC00"]]},
-
-{"description": "Valid numeric entity character U+AFFFD",
-"input": "",
-"output": [["Character", "\uDA7F\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+B0000",
-"input": "",
-"output": [["Character", "\uDA80\uDC00"]]},
-
-{"description": "Valid numeric entity character U+BFFFD",
-"input": "",
-"output": [["Character", "\uDABF\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+C0000",
-"input": "",
-"output": [["Character", "\uDAC0\uDC00"]]},
-
-{"description": "Valid numeric entity character U+CFFFD",
-"input": "",
-"output": [["Character", "\uDAFF\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+D0000",
-"input": "",
-"output": [["Character", "\uDB00\uDC00"]]},
-
-{"description": "Valid numeric entity character U+DFFFD",
-"input": "",
-"output": [["Character", "\uDB3F\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+E0000",
-"input": "",
-"output": [["Character", "\uDB40\uDC00"]]},
-
-{"description": "Valid numeric entity character U+EFFFD",
-"input": "",
-"output": [["Character", "\uDB7F\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+F0000",
-"input": "",
-"output": [["Character", "\uDB80\uDC00"]]},
-
-{"description": "Valid numeric entity character U+FFFFD",
-"input": "",
-"output": [["Character", "\uDBBF\uDFFD"]]},
-
-{"description": "Valid numeric entity character U+100000",
-"input": "",
-"output": [["Character", "\uDBC0\uDC00"]]},
-
-{"description": "Valid numeric entity character U+10FFFD",
-"input": "",
-"output": [["Character", "\uDBFF\uDFFD"]]}
-
-]}
-
-
diff --git a/libs/html5lib/tests/testdata/tokenizer/pendingSpecChanges.test b/libs/html5lib/tests/testdata/tokenizer/pendingSpecChanges.test
deleted file mode 100644
index 1b7dc3c72..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/pendingSpecChanges.test
+++ /dev/null
@@ -1,7 +0,0 @@
-{"tests": [
-
-{"description":"",
- "output":[["Comment", "comment"]]},
-
-{"description":"Comment, Central dash no space",
- "input":"",
- "output":["ParseError", ["Comment", "-"]]},
-
-{"description":"Comment, two central dashes",
-"input":"",
-"output":["ParseError", ["Comment", " --comment "]]},
-
-{"description":"Unfinished comment",
-"input":"",
- "output":["ParseError", ["Comment", ""]]},
-
-{"description":"Short comment two",
- "input":"",
- "output":["ParseError", ["Comment", ""]]},
-
-{"description":"Short comment three",
- "input":"",
- "output":[["Comment", ""]]},
-
-
-{"description":"Ampersand EOF",
-"input":"&",
-"output":[["Character", "&"]]},
-
-{"description":"Ampersand ampersand EOF",
-"input":"&&",
-"output":[["Character", "&&"]]},
-
-{"description":"Ampersand space EOF",
-"input":"& ",
-"output":[["Character", "& "]]},
-
-{"description":"Unfinished entity",
-"input":"&f",
-"output":[["Character", "&f"]]},
-
-{"description":"Ampersand, number sign",
-"input":"",
-"output":["ParseError", ["Character", ""]]},
-
-{"description":"Unfinished numeric entity",
-"input":"",
-"output":["ParseError", ["Character", ""]]},
-
-{"description":"Entity with trailing semicolon (1)",
-"input":"I'm ¬it",
-"output":[["Character","I'm \u00ACit"]]},
-
-{"description":"Entity with trailing semicolon (2)",
-"input":"I'm ∉",
-"output":[["Character","I'm \u2209"]]},
-
-{"description":"Entity without trailing semicolon (1)",
-"input":"I'm ¬it",
-"output":[["Character","I'm "], "ParseError", ["Character", "\u00ACit"]]},
-
-{"description":"Entity without trailing semicolon (2)",
-"input":"I'm ¬in",
-"output":[["Character","I'm "], "ParseError", ["Character", "\u00ACin"]]},
-
-{"description":"Partial entity match at end of file",
-"input":"I'm &no",
-"output":[["Character","I'm &no"]]},
-
-{"description":"Non-ASCII character reference name",
-"input":"&\u00AC;",
-"output":[["Character", "&\u00AC;"]]},
-
-{"description":"ASCII decimal entity",
-"input":"$",
-"output":[["Character","$"]]},
-
-{"description":"ASCII hexadecimal entity",
-"input":"?",
-"output":[["Character","?"]]},
-
-{"description":"Hexadecimal entity in attribute",
-"input":"",
-"output":[["StartTag", "h", {"a":"?"}], ["EndTag", "h"]]},
-
-{"description":"Entity in attribute without semicolon ending in x",
-"input":"",
-"output":[["StartTag", "h", {"a":"¬x"}]]},
-
-{"description":"Entity in attribute without semicolon ending in 1",
-"input":"",
-"output":[["StartTag", "h", {"a":"¬1"}]]},
-
-{"description":"Entity in attribute without semicolon ending in i",
-"input":"",
-"output":[["StartTag", "h", {"a":"¬i"}]]},
-
-{"description":"Entity in attribute without semicolon",
-"input":"",
-"output":["ParseError", ["StartTag", "h", {"a":"\u00A9"}]]},
-
-{"description":"Unquoted attribute ending in ampersand",
-"input":"",
-"output":[["StartTag","s",{"o":"&","t":""}]]},
-
-{"description":"Unquoted attribute at end of tag with final character of &, with tag followed by characters",
-"input":"foo",
-"output":[["StartTag", "a", {"a":"a&"}], ["Character", "foo"]]},
-
-{"description":"plaintext element",
- "input":"foobar",
- "output":[["StartTag","plaintext",{}], ["Character","foobar"]]},
-
-{"description":"Open angled bracket in unquoted attribute value state",
- "input":"",
- "output":["ParseError", ["StartTag", "a", {"a":"f<"}]]}
-
-]}
diff --git a/libs/html5lib/tests/testdata/tokenizer/test2.test b/libs/html5lib/tests/testdata/tokenizer/test2.test
deleted file mode 100644
index 87a8eba34..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/test2.test
+++ /dev/null
@@ -1,179 +0,0 @@
-{"tests": [
-
-{"description":"DOCTYPE without name",
-"input":"",
-"output":["ParseError", "ParseError", ["DOCTYPE", null, null, null, false]]},
-
-{"description":"DOCTYPE without space before name",
-"input":"",
-"output":["ParseError", ["DOCTYPE", "html", null, null, true]]},
-
-{"description":"Incorrect DOCTYPE without a space before name",
-"input":"",
-"output":["ParseError", ["DOCTYPE", "foo", null, null, true]]},
-
-{"description":"DOCTYPE with publicId",
-"input":"",
-"output":[["DOCTYPE", "html", "-//W3C//DTD HTML Transitional 4.01//EN", null, true]]},
-
-{"description":"DOCTYPE with EOF after PUBLIC",
-"input":"",
-"output":[["DOCTYPE", "html", null, "-//W3C//DTD HTML Transitional 4.01//EN", true]]},
-
-{"description":"DOCTYPE with publicId and systemId",
-"input":"",
-"output":[["DOCTYPE", "html", "-//W3C//DTD HTML Transitional 4.01//EN", "-//W3C//DTD HTML Transitional 4.01//EN", true]]},
-
-{"description":"DOCTYPE with > in double-quoted publicId",
-"input":"x",
-"output":["ParseError", ["DOCTYPE", "html", "", null, false], ["Character", "x"]]},
-
-{"description":"DOCTYPE with > in single-quoted publicId",
-"input":"x",
-"output":["ParseError", ["DOCTYPE", "html", "foo", "", false], ["Character", "x"]]},
-
-{"description":"Incomplete doctype",
-"input":"",
-"output":[["StartTag", "h", { "a":"&" }]]},
-
-{"description":"StartTag containing <",
-"input":"",
-"output":[["StartTag", "a",
-"output":[["StartTag","h",{},true]]},
-
-{"description":"Void element with permitted slash",
-"input":"
",
-"output":[["StartTag","br",{},true]]},
-
-{"description":"Void element with permitted slash (with attribute)",
-"input":"
",
-"output":[["StartTag","br",{"foo":"bar"},true]]},
-
-{"description":"StartTag containing /",
-"input":"",
-"output":["ParseError", ["StartTag", "h", { "a":"b" }]]},
-
-{"description":"Double-quoted attribute value",
-"input":"",
-"output":[["StartTag", "h", { "a":"b" }]]},
-
-{"description":"Unescaped ",
-"input":"",
-"output":["ParseError", ["Character", ""]]},
-
-{"description":"Illegal end tag name",
-"input":"1>",
-"output":["ParseError", ["Comment", "1"]]},
-
-{"description":"Simili processing instruction",
-"input":"",
-"output":["ParseError", ["Comment", "?namespace"]]},
-
-{"description":"A bogus comment stops at >, even if preceeded by two dashes",
-"input":"",
-"output":["ParseError", ["Comment", "?foo--"]]},
-
-{"description":"Unescaped <",
-"input":"foo < bar",
-"output":[["Character", "foo "], "ParseError", ["Character", "< bar"]]},
-
-{"description":"Null Byte Replacement",
-"input":"\u0000",
-"output":["ParseError", ["Character", "\u0000"]]},
-
-{"description":"Comment with dash",
-"input":"c",
-"output":[["Character", "a"], "ParseError", ["Comment", "b"], ["Character", "c"]]},
-
-{"description":"Empty end tag with following end tag",
-"input":"a>c",
-"output":[["Character", "a"], "ParseError", ["EndTag", "b"], ["Character", "c"]]}
-
-]}
diff --git a/libs/html5lib/tests/testdata/tokenizer/test3.test b/libs/html5lib/tests/testdata/tokenizer/test3.test
deleted file mode 100644
index 8fc529a2b..000000000
--- a/libs/html5lib/tests/testdata/tokenizer/test3.test
+++ /dev/null
@@ -1,6047 +0,0 @@
-{"tests": [
-
-{"description":"",
-"input":"",
-"output":[]},
-
-{"description":"\\u0009",
-"input":"\u0009",
-"output":[["Character", "\u0009"]]},
-
-{"description":"\\u000A",
-"input":"\u000A",
-"output":[["Character", "\u000A"]]},
-
-{"description":"\\u000B",
-"input":"\u000B",
-"output":["ParseError", ["Character", "\u000B"]]},
-
-{"description":"\\u000C",
-"input":"\u000C",
-"output":[["Character", "\u000C"]]},
-
-{"description":" ",
-"input":" ",
-"output":[["Character", " "]]},
-
-{"description":"!",
-"input":"!",
-"output":[["Character", "!"]]},
-
-{"description":"\"",
-"input":"\"",
-"output":[["Character", "\""]]},
-
-{"description":"%",
-"input":"%",
-"output":[["Character", "%"]]},
-
-{"description":"&",
-"input":"&",
-"output":[["Character", "&"]]},
-
-{"description":"'",
-"input":"'",
-"output":[["Character", "'"]]},
-
-{"description":",",
-"input":",",
-"output":[["Character", ","]]},
-
-{"description":"-",
-"input":"-",
-"output":[["Character", "-"]]},
-
-{"description":".",
-"input":".",
-"output":[["Character", "."]]},
-
-{"description":"/",
-"input":"/",
-"output":[["Character", "/"]]},
-
-{"description":"0",
-"input":"0",
-"output":[["Character", "0"]]},
-
-{"description":"1",
-"input":"1",
-"output":[["Character", "1"]]},
-
-{"description":"9",
-"input":"9",
-"output":[["Character", "9"]]},
-
-{"description":";",
-"input":";",
-"output":[["Character", ";"]]},
-
-{"description":"<",
-"input":"<",
-"output":["ParseError", ["Character", "<"]]},
-
-{"description":"<\\u0000",
-"input":"<\u0000",
-"output":["ParseError", ["Character", "<"], "ParseError", ["Character", "\u0000"]]},
-
-{"description":"<\\u0009",
-"input":"<\u0009",
-"output":["ParseError", ["Character", "<\u0009"]]},
-
-{"description":"<\\u000A",
-"input":"<\u000A",
-"output":["ParseError", ["Character", "<\u000A"]]},
-
-{"description":"<\\u000B",
-"input":"<\u000B",
-"output":["ParseError", "ParseError", ["Character", "<\u000B"]]},
-
-{"description":"<\\u000C",
-"input":"<\u000C",
-"output":["ParseError", ["Character", "<\u000C"]]},
-
-{"description":"< ",
-"input":"< ",
-"output":["ParseError", ["Character", "< "]]},
-
-{"description":"",
-"input":"",
-"input":"",
-"output":["ParseError", ["Comment", "-- "]]},
-
-{"description":"",
-"input":"",
-"output":["ParseError", ["Comment", "-- "]]},
-
-{"description":"",
-"input":"",
-"output":["ParseError", ["Comment", "-- a"]]},
-
-{"description":"",
-"input":"",
-"output":["ParseError", ["Comment", ""]]},
-
-{"description":"",
-"input":"",
-"output":["ParseError", ["Comment", "--!a"]]},
-
-{"description":"",
-"input":"",
-"output":["ParseError", ["Comment", "--!"]]},
-
-{"description":"",
-"input":"",
-"output":[["Comment", ""]]},
-
-{"description":"",
-"input":"",
-"output":["ParseError", ["Comment", ""]]},
-
-{"description":"",
-"input":"",
-"output":["ParseError", ["Comment", ""]]},
-
-{"description":"",
-"output":["ParseError",["Comment"," foo - - bar "]]},
-
-{"description":"FF between attributes",
-"input":"",
-"output":[["StartTag","a",{"b":"","c":""}]]}
-]}
-
-
diff --git a/libs/html5lib/tests/testdata/tree-construction/README.md b/libs/html5lib/tests/testdata/tree-construction/README.md
deleted file mode 100644
index 18a85ecff..000000000
--- a/libs/html5lib/tests/testdata/tree-construction/README.md
+++ /dev/null
@@ -1,104 +0,0 @@
-Tree Construction Tests
-=======================
-
-Each file containing tree construction tests consists of any number of
-tests separated by two newlines (LF) and a single newline before the end
-of the file. For instance:
-
- [TEST]LF
- LF
- [TEST]LF
- LF
- [TEST]LF
-
-Where [TEST] is the following format:
-
-Each test must begin with a string "\#data" followed by a newline (LF).
-All subsequent lines until a line that says "\#errors" are the test data
-and must be passed to the system being tested unchanged, except with the
-final newline (on the last line) removed.
-
-Then there must be a line that says "\#errors". It must be followed by
-one line per parse error that a conformant checker would return. It
-doesn't matter what those lines are, although they can't be
-"\#document-fragment", "\#document", "\#script-off", "\#script-on", or
-empty, the only thing that matters is that there be the right number
-of parse errors.
-
-Then there \*may\* be a line that says "\#document-fragment", which must
-be followed by a newline (LF), followed by a string of characters that
-indicates the context element, followed by a newline (LF). If the string
-of characters starts with "svg ", the context element is in the SVG
-namespace and the substring after "svg " is the local name. If the
-string of characters starts with "math ", the context element is in the
-MathML namespace and the substring after "math " is the local name.
-Otherwise, the context element is in the HTML namespace and the string
-is the local name. If this line is present the "\#data" must be parsed
-using the HTML fragment parsing algorithm with the context element as
-context.
-
-Then there \*may\* be a line that says "\#script-off" or
-"\#script-on". If a line that says "\#script-off" is present, the
-parser must set the scripting flag to disabled. If a line that says
-"\#script-on" is present, it must set it to enabled. Otherwise, the
-test should be run in both modes.
-
-Then there must be a line that says "\#document", which must be followed
-by a dump of the tree of the parsed DOM. Each node must be represented
-by a single line. Each line must start with "| ", followed by two spaces
-per parent node that the node has before the root document node.
-
-- Element nodes must be represented by a "`<`" then the *tag name
- string* "`>`", and all the attributes must be given, sorted
- lexicographically by UTF-16 code unit according to their *attribute
- name string*, on subsequent lines, as if they were children of the
- element node.
-- Attribute nodes must have the *attribute name string*, then an "="
- sign, then the attribute value in double quotes (").
-- Text nodes must be the string, in double quotes. Newlines aren't
- escaped.
-- Comments must be "`<`" then "`!-- `" then the data then "` -->`".
-- DOCTYPEs must be "``".
-- Processing instructions must be "``", then the target, then a
- space, then the data and then "`>`". (The HTML parser cannot emit
- processing instructions, but scripts can, and the WebVTT to DOM
- rules can emit them.)
-- Template contents are represented by the string "content" with the
- children below it.
-
-The *tag name string* is the local name prefixed by a namespace
-designator. For the HTML namespace, the namespace designator is the
-empty string, i.e. there's no prefix. For the SVG namespace, the
-namespace designator is "svg ". For the MathML namespace, the namespace
-designator is "math ".
-
-The *attribute name string* is the local name prefixed by a namespace
-designator. For no namespace, the namespace designator is the empty
-string, i.e. there's no prefix. For the XLink namespace, the namespace
-designator is "xlink ". For the XML namespace, the namespace designator
-is "xml ". For the XMLNS namespace, the namespace designator is "xmlns
-". Note the difference between "xlink:href" which is an attribute in no
-namespace with the local name "xlink:href" and "xlink href" which is an
-attribute in the xlink namespace with the local name "href".
-
-If there is also a "\#document-fragment" the bit following "\#document"
-must be a representation of the HTML fragment serialization for the
-context element given by "\#document-fragment".
-
-For example:
-
- #data
- One
Two
- #errors
- 3: Missing document type declaration
- #document
- |
- |
- |
- |
- | "One"
- |
- | "Two"
diff --git a/libs/html5lib/tests/testdata/tree-construction/adoption01.dat b/libs/html5lib/tests/testdata/tree-construction/adoption01.dat
deleted file mode 100644
index 38f98efde..000000000
--- a/libs/html5lib/tests/testdata/tree-construction/adoption01.dat
+++ /dev/null
@@ -1,354 +0,0 @@
-#data
-
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,10): adoption-agency-1.3
-#document
-|
-|
-|
-|
-|
-|
-
-#data
-12
3
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,12): adoption-agency-1.3
-#document
-|
-|
-|
-|
-| "1"
-|
-|
-| "2"
-| "3"
-
-#data
-13
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,17): adoption-agency-1.3
-#document
-|
-|
-|
-|
-| "1"
-|
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,12): adoption-agency-1.3
-#document
-|
-|
-|
-|
-| "1"
-|
-| "2"
-|
-| "3"
-
-#data
-1
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,20): adoption-agency-1.3
-(1,20): adoption-agency-1.3
-#document
-|
-|
-|
-|
-| "1"
-|
-|
-| "2"
-|
-|
-| "3"
-| "4"
-| "5"
-
-#data
-12
3
-#errors
-(1,7): expected-doctype-but-got-start-tag
-(1,10): unexpected-start-tag-implies-table-voodoo
-(1,11): unexpected-character-implies-table-voodoo
-(1,14): unexpected-start-tag-implies-table-voodoo
-(1,15): unexpected-character-implies-table-voodoo
-(1,19): unexpected-end-tag-implies-table-voodoo
-(1,19): adoption-agency-1.3
-(1,20): unexpected-character-implies-table-voodoo
-(1,24): unexpected-end-tag-implies-table-voodoo
-(1,24): eof-in-table
-#document
-|
-|
-|
-|
-| "1"
-|
-|
-| "2"
-| "3"
-|
-
-#data
-
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,16): adoption-agency-1.3
-(1,16): expected-closing-tag-but-got-eof
-#document
-|
-|
-|
-|
-|
-|
-|
-|
-
-#data
-
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,16): adoption-agency-1.3
-(1,16): expected-closing-tag-but-got-eof
-#document
-|
-|
-|
-|
-|
-|
-|
-|
-|
-
-#data
-
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,16): adoption-agency-1.3
-(1,16): expected-closing-tag-but-got-eof
-#document
-|
-|
-|
-|
-|
-|
-|
-|
-|
-|
-
-#data
-123
45
-#errors
-(1,3): expected-doctype-but-got-start-tag
-(1,30): unexpected-end-tag
-(1,35): adoption-agency-1.3
-#document
-|
-|
-|
-|
-| "1"
-|
-| id="A"
-| "2"
-|
-| id="B"
-| "3"
-|
-| id="A"
-|
-| id="B"
-| "4"
-|
-| id="B"
-| "5"
-
-#data
-
-#errors
-(1,7): expected-doctype-but-got-start-tag
-(1,10): unexpected-start-tag-implies-table-voodoo
-(1,11): unexpected-character-implies-table-voodoo
-(1,15): unexpected-cell-in-table-body
-(1,30): unexpected-implied-end-tag-in-table-view
-#document
-|
-|
-|
-|
-| "1"
-|
-| "3"
-|
-|
-|
-|
-| "2"
-
-#data
-
-#errors
-(1,7): expected-doctype-but-got-start-tag
-(1,8): unexpected-character-implies-table-voodoo
-(1,12): unexpected-cell-in-table-body
-(1,22): unexpected-character-implies-table-voodoo
-#document
-|
-|
-|
-| "AC"
-| |
-#errors
-(1,9): expected-doctype-but-got-end-tag
-(1,9): unexpected-end-tag-before-html
-(1,13): unexpected-end-tag-before-html
-(1,18): unexpected-end-tag-before-html
-(1,22): unexpected-end-tag-before-html
-(1,26): unexpected-end-tag-before-html
-(1,35): unexpected-end-tag-before-html
-(1,39): unexpected-end-tag-before-html
-(1,47): unexpected-end-tag-before-html
-(1,52): unexpected-end-tag-before-html
-(1,58): unexpected-end-tag-before-html
-(1,64): unexpected-end-tag-before-html
-(1,72): unexpected-end-tag-before-html
-(1,79): unexpected-end-tag-before-html
-(1,88): unexpected-end-tag-before-html
-(1,93): unexpected-end-tag-before-html
-(1,98): unexpected-end-tag-before-html
-(1,103): unexpected-end-tag-before-html
-(1,108): unexpected-end-tag-before-html
-(1,113): unexpected-end-tag-before-html
-(1,118): unexpected-end-tag-before-html
-(1,130): unexpected-end-tag-after-body
-(1,130): unexpected-end-tag-treated-as
-(1,134): unexpected-end-tag
-(1,140): unexpected-end-tag
-(1,148): unexpected-end-tag
-(1,155): unexpected-end-tag
-(1,163): unexpected-end-tag
-(1,172): unexpected-end-tag
-(1,180): unexpected-end-tag
-(1,185): unexpected-end-tag
-(1,190): unexpected-end-tag
-(1,195): unexpected-end-tag
-(1,203): unexpected-end-tag
-(1,210): unexpected-end-tag
-(1,217): unexpected-end-tag
-(1,225): unexpected-end-tag
-(1,230): unexpected-end-tag
-(1,238): unexpected-end-tag
-(1,244): unexpected-end-tag
-(1,251): unexpected-end-tag
-(1,258): unexpected-end-tag
-(1,269): unexpected-end-tag
-(1,279): unexpected-end-tag
-(1,287): unexpected-end-tag
-(1,296): unexpected-end-tag
-(1,300): unexpected-end-tag
-(1,305): unexpected-end-tag
-(1,310): unexpected-end-tag
-(1,320): unexpected-end-tag
-(1,331): unexpected-end-tag
-(1,339): unexpected-end-tag
-(1,347): unexpected-end-tag
-(1,355): unexpected-end-tag
-(1,365): end-tag-too-early
-(1,378): end-tag-too-early
-(1,387): end-tag-too-early
-(1,393): end-tag-too-early
-(1,399): end-tag-too-early
-(1,404): end-tag-too-early
-(1,415): end-tag-too-early
-(1,425): end-tag-too-early
-(1,432): end-tag-too-early
-(1,437): end-tag-too-early
-(1,442): end-tag-too-early
-(1,447): unexpected-end-tag
-(1,454): unexpected-end-tag
-(1,460): unexpected-end-tag
-(1,467): unexpected-end-tag
-(1,476): end-tag-too-early
-(1,486): end-tag-too-early
-(1,495): end-tag-too-early
-(1,513): expected-eof-but-got-end-tag
-(1,513): unexpected-end-tag
-(1,520): unexpected-end-tag
-(1,529): unexpected-end-tag
-(1,537): unexpected-end-tag
-(1,547): unexpected-end-tag
-(1,557): unexpected-end-tag
-(1,568): unexpected-end-tag
-(1,579): unexpected-end-tag
-(1,590): unexpected-end-tag
-(1,599): unexpected-end-tag
-(1,611): unexpected-end-tag
-(1,622): unexpected-end-tag
-#document
-|
-|
-|
-|
-|
-
-#data
-
-#errors
-(1,7): expected-doctype-but-got-start-tag
-(1,20): unexpected-end-tag-implies-table-voodoo
-(1,20): unexpected-end-tag
-(1,24): unexpected-end-tag-implies-table-voodoo
-(1,24): unexpected-end-tag
-(1,29): unexpected-end-tag-implies-table-voodoo
-(1,29): unexpected-end-tag
-(1,33): unexpected-end-tag-implies-table-voodoo
-(1,33): unexpected-end-tag
-(1,37): unexpected-end-tag-implies-table-voodoo
-(1,37): unexpected-end-tag
-(1,46): unexpected-end-tag-implies-table-voodoo
-(1,46): unexpected-end-tag
-(1,50): unexpected-end-tag-implies-table-voodoo
-(1,50): unexpected-end-tag
-(1,58): unexpected-end-tag-implies-table-voodoo
-(1,58): unexpected-end-tag
-(1,63): unexpected-end-tag-implies-table-voodoo
-(1,63): unexpected-end-tag
-(1,69): unexpected-end-tag-implies-table-voodoo
-(1,69): end-tag-too-early
-(1,75): unexpected-end-tag-implies-table-voodoo
-(1,75): unexpected-end-tag
-(1,83): unexpected-end-tag-implies-table-voodoo
-(1,83): unexpected-end-tag
-(1,90): unexpected-end-tag-implies-table-voodoo
-(1,90): unexpected-end-tag
-(1,99): unexpected-end-tag-implies-table-voodoo
-(1,99): unexpected-end-tag
-(1,104): unexpected-end-tag-implies-table-voodoo
-(1,104): end-tag-too-early
-(1,109): unexpected-end-tag-implies-table-voodoo
-(1,109): end-tag-too-early
-(1,114): unexpected-end-tag-implies-table-voodoo
-(1,114): end-tag-too-early
-(1,119): unexpected-end-tag-implies-table-voodoo
-(1,119): end-tag-too-early
-(1,124): unexpected-end-tag-implies-table-voodoo
-(1,124): end-tag-too-early
-(1,129): unexpected-end-tag-implies-table-voodoo
-(1,129): end-tag-too-early
-(1,136): unexpected-end-tag-in-table-row
-(1,141): unexpected-end-tag-implies-table-voodoo
-(1,141): unexpected-end-tag-treated-as
-(1,145): unexpected-end-tag-implies-table-voodoo
-(1,145): unexpected-end-tag
-(1,151): unexpected-end-tag-implies-table-voodoo
-(1,151): unexpected-end-tag
-(1,159): unexpected-end-tag-implies-table-voodoo
-(1,159): unexpected-end-tag
-(1,166): unexpected-end-tag-implies-table-voodoo
-(1,166): unexpected-end-tag
-(1,174): unexpected-end-tag-implies-table-voodoo
-(1,174): unexpected-end-tag
-(1,183): unexpected-end-tag-implies-table-voodoo
-(1,183): unexpected-end-tag
-(1,196): unexpected-end-tag
-(1,201): unexpected-end-tag
-(1,206): unexpected-end-tag
-(1,214): unexpected-end-tag
-(1,221): unexpected-end-tag
-(1,228): unexpected-end-tag
-(1,236): unexpected-end-tag
-(1,241): unexpected-end-tag
-(1,249): unexpected-end-tag
-(1,255): unexpected-end-tag
-(1,262): unexpected-end-tag
-(1,269): unexpected-end-tag
-(1,280): unexpected-end-tag
-(1,290): unexpected-end-tag
-(1,298): unexpected-end-tag
-(1,307): unexpected-end-tag
-(1,311): unexpected-end-tag
-(1,316): unexpected-end-tag
-(1,321): unexpected-end-tag
-(1,331): unexpected-end-tag
-(1,342): unexpected-end-tag
-(1,350): unexpected-end-tag
-(1,358): unexpected-end-tag
-(1,366): unexpected-end-tag
-(1,376): end-tag-too-early
-(1,389): end-tag-too-early
-(1,398): end-tag-too-early
-(1,404): end-tag-too-early
-(1,410): end-tag-too-early
-(1,415): end-tag-too-early
-(1,426): end-tag-too-early
-(1,436): end-tag-too-early
-(1,443): end-tag-too-early
-(1,448): end-tag-too-early
-(1,453): end-tag-too-early
-(1,458): unexpected-end-tag
-(1,465): unexpected-end-tag
-(1,471): unexpected-end-tag
-(1,478): unexpected-end-tag
-(1,487): end-tag-too-early
-(1,497): end-tag-too-early
-(1,506): end-tag-too-early
-(1,524): expected-eof-but-got-end-tag
-(1,524): unexpected-end-tag
-(1,531): unexpected-end-tag
-(1,540): unexpected-end-tag
-(1,548): unexpected-end-tag
-(1,558): unexpected-end-tag
-(1,568): unexpected-end-tag
-(1,579): unexpected-end-tag
-(1,590): unexpected-end-tag
-(1,601): unexpected-end-tag
-(1,610): unexpected-end-tag
-(1,622): unexpected-end-tag
-(1,633): unexpected-end-tag
-#document
-|
-|
-|
-|
-|
-|
-|
-|
-
-#data
-